Ver Mensaje Individual
  #5  
Antiguo 02-03-2024
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.197
Reputación: 20
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 *Controlint Index,
          
TRect &RectTOwnerDrawState State);
private:
  
TWndMethod OldCBProc;
  
void __fastcall CBProc(TMessageMessage);

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


Este sería el archivo.cpp

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

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

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

void __fastcall TForm1::CBProc(TMessageMessage)
{
  
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(hDCComboBox1->Font->Handle);
    
TEXTMETRIC Metric;
    
GetTextMetrics(hDC, &Metric);
    
FillRect(hDC, &RectGetSysColorBrush(COLOR_WINDOW));
    
SetTextAlign(hDCTA_CENTER);
       
// Escribimos Text centrado
    
ExtTextOut(hDCRect.Right/2, (Rect.Bottom Metric.tmHeight)/1ETO_CLIPPED, &RectTextstrlen(Text), 0);
   
    
// Liberamos el HDC
    
ReleaseDC(hDCComboBox1->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