Ver Mensaje Individual
  #3  
Antiguo 02-03-2024
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.211
Reputación: 22
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Para conseguir que un ComboBox estilo csOwnerDrawFixed escriba el Texto cuando su ItemIndex es -1, es decir, cuando no se ha elegido ninguna opción, podemos realizar un SubClassing y manejar el mensaje WM_PAINT.

Dado que la propiedad Text del ComboBox queda inhabilitada, en el ejemplo uso el Tag para almacenar un puntero char pero el texto se puede manejar como se quiera, siempre y cuando la función CBProc que va a tratar el Mensaje WM_PAINT tenga acceso a él.

Nótese que el tratamiento de WM_PAINT se realiza con API y no con VCL, esto es debido a que WM_PAINT empieza a ser llamado antes de que el Canvas del ComboBox esté operativo.

Muestro un ejemplo completo de un formulario con un ComboBox.


Este sería el archivo.h

Código PHP:
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>

//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // IDE-managed Components
  
TComboBox *ComboBox1;
  
void __fastcall ComboBox1DrawItem(TWinControl *Control, int Index,
          
TRect &Rect, TOwnerDrawState State);
private:
  
TWndMethod OldCBProc;
  
void __fastcall CBProc(TMessage& Message);

public:        
// User declarations
  
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif 


Este sería el archivo.cpp

Código PHP:
// Realiza un SubClassing sobre un TWinControl
void __fastcall SetSubClass(TWinControl *WC, TWndMethod newProc, TWndMethod *oldProc)
{
  *
oldProc = WC->WindowProc;
  
WC->WindowProc = newProc;
}

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
  : 
TForm(Owner)
{
  
// Realizamos el SubClassing
  
SetSubClass(ComboBox1, CBProc, &OldCBProc);
   
// Guardamos el Texto en el Tag
  
ComboBox1->Tag = (LONG_PTR)"Elija una Opción";
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ComboBox1DrawItem(TWinControl *Control, int Index,
      
TRect &Rect, TOwnerDrawState State)
{
  
TComboBox *CB = dynamic_cast<TComboBox*>(Control);
  if(
CB){
    
Rect.Right -= GetSystemMetrics(SM_CXVSCROLL);
    
SetTextAlign(CB->Canvas->Handle, TA_CENTER);
    
CB->Canvas->TextOut(Rect.Right/2, Rect.Top + (CB->ItemHeight + CB->Font->Height)/2, CB->Items->Strings[Index]);
  }
}
//---------------------------------------------------------------------------

void __fastcall TForm1::CBProc(TMessage& Message)
{
  
OldCBProc(Message);  // Permitimos que primero se traten por defecto todos los mensajes 
    // Tratamos nuestro WM_PAINT
  
if((Message.Msg == WM_PAINT || Message.Msg == WM_SETFOCUS) && ComboBox1->ItemIndex < 0){
    
// Preparamos el Texto
    
char *Text = (char*)ComboBox1->Tag;
    
// Preparamos el rectángulo apropiado
    
TRect Rect = ComboBox1->ClientRect;
    
InflateRect(&Rect, -2, -2);
    
Rect.Right -= GetSystemMetrics(SM_CXVSCROLL); // Para salvar el botón del ComboBox

    //Preparamos un HDC con la fuente del ComboBox y seleccionamos la alineación al centro
    
HDC hDC = GetDC(ComboBox1->Handle);
    
SelectObject(hDC, ComboBox1->Font->Handle);
    
TEXTMETRIC Metric;
    
GetTextMetrics(hDC, &Metric);
    
FillRect(hDC, &Rect, GetSysColorBrush(COLOR_WINDOW));
    
SetTextAlign(hDC, TA_CENTER);
       
// Escribimos Text centrado
    
ExtTextOut(hDC, Rect.Right/2, (Rect.Bottom - Metric.tmHeight)/2 + 1, ETO_CLIPPED, &Rect, Text, strlen(Text), 0);
   
    
// Liberamos el HDC
    
ReleaseDC(hDC, ComboBox1->Handle);
  }
} 
Espero que esto responda a tu pregunta.


Saludos.

Última edición por escafandra fecha: 02-03-2024 a las 23:07:55.
Responder Con Cita