Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Otros entornos y lenguajes > C++ Builder
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 22-10-2004
Sonic Sonic is offline
Miembro
 
Registrado: may 2004
Posts: 40
Poder: 0
Sonic Va por buen camino
Tab en RichEdit

Buenas a todos!

¿Alguien sabe cómo puedo acceder o cambiar el numero de espacios que equivalen a una pulsación de la tecla Tab?

Estoy haciendo un Editor y me gustaría hacer que se pudiese elegir el tamaño del Tab, pero no encuentro la forma.

Gracias de antemano
Responder Con Cita
  #2  
Antiguo 22-10-2004
Avatar de barman
barman barman is offline
Miembro
 
Registrado: may 2003
Posts: 139
Poder: 21
barman Va por buen camino
Si estas trajando con el RichtEdit

RichEdit1->Paragraph->Alignment
RichEdit1->Paragraph->Numbering

Si con TMemo, tendras que capturar el evento OnKeyDown, y comprobar
el Key = VK_TAB
Responder Con Cita
  #3  
Antiguo 25-10-2004
Sonic Sonic is offline
Miembro
 
Registrado: may 2004
Posts: 40
Poder: 0
Sonic Va por buen camino
Cita:
Empezado por barman
Si estas trajando con el RichtEdit

RichEdit1->Paragraph->Alignment
RichEdit1->Paragraph->Numbering

Si con TMemo, tendras que capturar el evento OnKeyDown, y comprobar
el Key = VK_TAB
Gracias barman, pero no entiendo como pueden ayudarme esas propiedades. Perdona que se me pasara, estoy trabajando con un TRichEdit y lo que pretendo es analizar las cadenas de texto para que cuando encuentre un \t pueda sustituirlo por el numero de espacios equivalentes, por eso necesito conocer qué propiedad me da dicho valor.

He visto que muchos editores sencillos te dan la opción de elegir el tamaño de tu tabulador, pero no consigo encontrar nada útil al respecto.

He mirado las propiedades que me has dado, pero ninguna me sirve para conocer el Tamaño del tab (o no sé usarlas que también puede ser). De todos modos te agradezco tu respuesta y me gustaría que si después de esta aclaración sigues pensando que mi solución está en las propiedades que me has dado, por favor me las aclares.

Muchas Gracias. Espero respuesta
Responder Con Cita
  #4  
Antiguo 25-10-2004
Avatar de barman
barman barman is offline
Miembro
 
Registrado: may 2003
Posts: 139
Poder: 21
barman Va por buen camino
A ver, el TRichtEdit es mas largo de lo que parece, basicamente tiene toda la funcionalidad de un editor de texto complejo, lo primero mirate el ejemplo que trae el compilador

.......Borlan5\CBuilder5\Examples\Apps\RichEdit\

Y seguro que resolvera todas tus dudas.

Por otra parte lo que me refiero es a esto.


void __fastcall TForm1::RichEdit1KeyPress(TObject *Sender, char &Key)
{
int StartPos = RichEdit1->SelStart + RichEdit1->SelLength;
if (Key == VK_TAB)
{
ShowMessage(StartPos);
Key = 0;
}

}
Responder Con Cita
  #5  
Antiguo 25-10-2004
Sonic Sonic is offline
Miembro
 
Registrado: may 2004
Posts: 40
Poder: 0
Sonic Va por buen camino
Buenas barman:

En los ejemplos no encuentro nada que me sirva y este código que has pegado tampoco hace nada de lo que necesito.

El codigo lo que hace es que cuando se pulse la tecla TAB salga por pantalla la suma del SelStart y del SelLength y aparte de que no se imprima el TAB. Y no le veo relación con lo que yo quiero hacer, ya que estos dos valores son la posición del cursor y de la longitud de la seleccion.

No sé, pero creo que no nos entendemos muy bien . Aunque por intentarlo que no quede..... .

Se me ocurre que quizá tu idea era que seleccionase con el ratón el un TAB escrito anteriormente y que el código me dijera la longitud, si es eso te adelanto que no funciona ya que la longitud del caracter \t es siempre 1.

Manualmente he comprobado que un TAB equivale a 9 espacios por defecto, y lo que yo quiero es poder cambiar eso (tanto acceder para obtener ese valor como acceder para cambiarlo).

Gracias de todas formas, sigo esperando respuesta.
Responder Con Cita
  #6  
Antiguo 29-10-2004
Avatar de barman
barman barman is offline
Miembro
 
Registrado: may 2003
Posts: 139
Poder: 21
barman Va por buen camino
Cita:
Empezado por Sonic
No sé, pero creo que no nos entendemos muy bien . Aunque por intentarlo que no quede..... .
Creo que no.
A ver por parte, 1º escribres y si pulsas el tabulador le envias 9 espacios.

void __fastcall TForm1::RichEdit1KeyUp(TObject *Sender, WORD &Key,
TShiftState Shift)
{
if (Key == VK_TAB)
{
RichEdit1 ->SetSelTextBuf(" ");
}

}


2º que lea el texto escrito y que cambie los Tabs por que quieras
SetSelTextBuf.

for (int i = 0; i< strlen(RichEdit1 ->Text.c_str()); i++ )
{
if (RichEdit1 ->Text.c_str()[i] == VK_TAB)
ShowMessage("A");
}
Responder Con Cita
  #7  
Antiguo 08-11-2004
Sonic Sonic is offline
Miembro
 
Registrado: may 2004
Posts: 40
Poder: 0
Sonic Va por buen camino
Al final ya entendí por donde ibas .

Muchas gracias por no rendirte, es buena la idea pero no me sirve, ya que eso sólo funciona para los textos que se escriban directamente en el RichEdit. Pero si importara un texto desde un archivo los Tabs no se procesarían y tendría que hacer una lectura del texto para cambiar los \t por grupos de 9 espacios. Y resulta que eso tampoco estaría bien porque
por otra parte, también comprendí que el simple hecho de haber planteado la pregunta era un error. Y es que un \t no equivale a ningún número de espacios (será por eso que no encontraba información). Si, al principio del texto, escribes " \t" el cursor se pondrá en el mismo lugar que si escribes "\t" solamente.

Quizás por eso no entendía tus explicaciones, porque yo buscaba algún mensaje a la API o alguna propiedad que me diera el número de espacios a que equivale un tab. Y no hacer yo mismo, que dicha equivalencia tuviera lugar. Y seguramente tú ya sabías mejor que yo lo que es un tab.

Al final resolví el problema por otros caminos, pero muchas gracias por tu ayuda.
Saludetes!
Responder Con Cita
  #8  
Antiguo 09-11-2004
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Cita:
Empezado por Sonic
Al final resolví el problema por otros caminos
Sería bienvenida tu explicación de esos otros caminos para quienes en un futuro se encuentren con un problema similar.

Por otra parte, desde que vi este hilo hace tiempo pensé: un RichEdit tiene una propiedad Paragraph.Tabs que es un arreglo de enteros que indican los puntos donde debe detenerse el tabulador.

Como ya bien notaste, un tabulador no corresponde a un número determinado de caracteres o espacios en blanco por una sencilla razón: a menos que la fuente que uses sea de ancho constante- como la Courier New - no tiene caso tratar de establecer el ancho de las tabulaciones en caracteres ya que éstos son de ancho variable.

Así que, en lugar de eso, las tabulaciones se indican en twips desde el margen izquierdo (según la documentación).

Ahora bien, como dije, había visto este hilo y pensado en la propiedad Paragraph.Tabs. Sin embargo no había dicho nada porque al probarlo yo mismo la mentada propiedad no funcionaba. Por más que le especificaba distintas medidas de tabulaciones, era como si no pasase nada y seguí poniendo las tabulaciones por defecto.

Pero yo había hecho esto alguna vez.

Finalmente, buscando en archivos viejos encontré cómo lo hice. Básicamente me olvidé de fijar las tabulaciones a través de la VCL y lo hice directamente mandando el mensaje EM_SETPARAFORMAT al control. En el código tengo algunos comentarios referentes a que la implementación de la VCL es incorrecta pero confieso que ya no recuerdo bien por qué, así como tampoco recuerdo exactamente qué es lo que hace el código.

Pero lo he probado y funciona.

El código está hecho pensando en una fuente de ancho fijo como Courier New de manera que en ese caso sí podía traducir los anchos de las tabulaciones en número de caracateres.

Como te digo, no puedo explicar los detalles porque ya no los recuerdo pero creo que puede servirte a tí o alguien más para ver por donde va el asunto.

El código es para Delphi pero debiera portarse sin problemas a C++.

Código Delphi [-]
(*
  Devuelve el ancho promedio de un caracter según la
  fuente seleccionada en el RichEdit.
*)
function TForm1.GetCharWidth;
var
  DC: HDC;
  TM: TTextMetric;
 
begin
  DC := GetDC(RichEdit1.Handle);
  SelectObject(DC, RichEdit1.Font.Handle);
  GetTextMetrics(DC, TM);
  Result := TM.tmAveCharWidth;
  ReleaseDC(RichEdit1.Handle, DC);
end;
 
(*
  Establece el ancho de las tabulaciones del RichEdit
  Usamos todas las tabulaciones del mismo ancho.
  La fórmula usada para establecer el ancho de cada
  tabulación es
  
    AnchoReal = 15*Value*CharWidth
*)
procedure TForm1.SetTabWidth(Value: Word);
var
  Paragraph: TParaFormat;
  Index: Integer;
 
begin
  // Establecer las posiciones de las tabulaciones
  with Paragraph do
  begin
    cbSize := SizeOf(TParaFormat);
    dwMask := PFM_TABSTOPS;
    cTabCount := MAX_TAB_STOPS;
    for Index := 0 to MAX_TAB_STOPS - 1 do
      rgxTabs[Index] := 15*(Index*Value + 1)*GetCharWidth;
  end;
 
  RichEdit1.Perform(EM_SETPARAFORMAT, 0, LParam(@Paragraph));
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  Paragraph: TParaFormat;
 
begin
  // Establecer márgenes izquierdo y derecho
  with Paragraph do
  begin
    cbSize := SizeOf(TParaFormat);
    dwMask := PFM_STARTINDENT or PFM_RIGHTINDENT;
    dxStartIndent := 15*GetCharWidth;
    dxRightIndent := 15*GetCharWidth;
  end;
 
  RichEdit1.Perform(EM_SETPARAFORMAT, 0, LParam(@Paragraph));
end;

La parte del FormCreate fue necesaria ya que la primera tabulación no la ponía donde yo quería de manera que establecí el margen con el mismo ancho que la tabulación.

Hace tiempo que hice este código así que desconozco si actualmente el "problema" con la VCL se ha solucionado. Aunque aparentemente no, o bien es simplemente cuestión de que no sé como usar la mencionada propiedad Paragraph.Tabs directamente.

// Saludos
Responder Con Cita
  #9  
Antiguo 23-11-2004
Sonic Sonic is offline
Miembro
 
Registrado: may 2004
Posts: 40
Poder: 0
Sonic Va por buen camino
El problema de los TABS surgió por la necesidad de hacer un Editor que se comportara de manera similar a la de Builder C++. Entre otras cosas lo que pretendía es que en una situación como esta:
Código:
			 
 		  linea 1 del texto
 				 linea2 del texto
Al situar el cursor justo delante de la 'l' de la segunda linea el Editor borrara todos los espacios necesarios para dejar la segunda linea al nivel de la primera, para ello necesitaba conocer a que distancia del margen se encontraba el primer caracter de cada linea. Y pensé que lo mejor era medir esa distancia en número de caracteres pensando erróneamente que el caracter \t podía equivaler a un número concreto de espacios (de ahí mi empeño por hallar una propiedad que me diera dicho número)

Hasta que no me di cuenta de que tal número no exístia por no ser '\t' un conjunto de caracteres como muy bien apuntaba Roman. No busqué otras soluciones.

Al final decidí que lo mejor par mi caso era medir la distancia al margen izquierdo en píxels para comparar las distintas lineas. Y así lo hice mediante el mensaje a la API "EM_POSFROMCHAR" que facilita la distancia en píxels a los márgenes izquierdo y superior de un TRichEdit si más que indicar la posición que ocupa el caracter al que se quiere hacer referencia.

Con este mensaje y algunas comparaciones mi problema quedó completamente resuelto.

Muchas gracias Roman por tus aclaraciones y por recordarme que escribiera el final de la historia.

Saludos a todos!
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro


La franja horaria es GMT +2. Ahora son las 17:00:04.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi