Comboboxgadget: Vertikale Ausrichtung des Inhalts

Für allgemeine Fragen zur Programmierung mit PureBasic.
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: Comboboxgadget: Vertikale Ausrichtung des Inhalts

Beitrag von ccode_new »

Hallo Windows-Api-Spezialisten (wie z.B. RSGrundausstattung :mrgreen: ),


wie behebt man eigentlich das Problem mit dem Markieren.


Wenn man beim Aufklappen mit der Maus über die Einträge fährt werden diese irgendwie fetter (farblich intensiver) Markiert.

Diese Markierung wird aber meist falsch positioniert.

Beim Auswählen kann man aber den richtigen Eintrag auswählen.


Wie kann man dieses Problem der mysteriösen verschobenen Markierung lösen ?
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Benutzeravatar
RSBasic
Admin
Beiträge: 8022
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: Comboboxgadget: Vertikale Ausrichtung des Inhalts

Beitrag von RSBasic »

@techniker
Du kannst dir das Konstantia-Program herunterladen und in das Eingabefeld einen beliebigen Wert eingeben und danach auf den Button "Konvertieren in Hexdezimal" drücken.
Dann kannst du herausfinden, ob dein Wunschwert bereits vergeben ist oder nicht.

@ccode_new
Meinst du deinen Code?
Bei mir unter Windows 10 werden die Einträge beim Hovern nicht zusätzlich hervorgehoben. Deshalb kann ich dir leider nicht helfen, da ich es nicht nachstellen kann.

Viele Grüße
RSGrundausstattung :lol:
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Benutzeravatar
techniker
Beiträge: 160
Registriert: 27.01.2016 11:08
Wohnort: BY

Re: Comboboxgadget: Vertikale Ausrichtung des Inhalts

Beitrag von techniker »

@RSBasic:

Danke! :)

Aber: Wie komme ich an den Zeiger lParam von #WM_DRAWITEM, wenn das Ereignis noch nicht aufgetreten ist?
Never change a running system - Never run a changed system!
(PB 6.03 LTS [x86])
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: Comboboxgadget: Vertikale Ausrichtung des Inhalts

Beitrag von ccode_new »

@RSBasic
Ja ich meine meinen Code.
Kommentiere das mal ein:
;FillRect_(*DRAWITEM\hDC,*DRAWITEM\rcItem,bgbrush)

Ich habe meinen Code mal etwas umgebaut und dabei diesen Befehl außer acht gelassen.

Wenn das Rechteck nicht ungefähr zeitgleich gefüllt wird kommt es zu diesem Problem.
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Benutzeravatar
Shardik
Beiträge: 738
Registriert: 25.01.2005 12:19

Re: Comboboxgadget: Vertikale Ausrichtung des Inhalts

Beitrag von Shardik »

Ich möchte auch einmal ein Beispiel zeigen (getestet mit Windows 7 x64 SP1 und PB 5.46 x86 im ASCII- und Unicode-Modus), das zwar den Text im ComboBoxGadget vertikal zentriert (und mit der eigentlich zu gering vorgegebenen Höhe auskommt), aber leider nicht mehr dem Originalaussehen entspricht, da die vertikale Zentrierung in allen meinen Versuchen nur mit Custom Drawing funktioniert hat:

Bild

Code: Alles auswählen

EnableExplicit

#CBEM_SETEXTENDEDSTYLE = #WM_USER + 14
#CBES_EX_NOSIZELIMIT = 8

Procedure WindowCallback(WindowHandle.I, Message.I, WParam.I, LParam.I)
  Protected Brush.I
  Protected *DrawItem.DRAWITEMSTRUCT
  Protected Result.I
  Protected ItemText.S

  Result = #PB_ProcessPureBasicEvents

  If Message = #WM_DRAWITEM
    *DrawItem = LParam

    If *DrawItem\CtlType = #ODT_COMBOBOX
      SetBkMode_(*DrawItem\hDC, #TRANSPARENT)

      If *DrawItem\ItemState & #ODS_FOCUS
        Brush = CreateSolidBrush_($FF901E)
        FillRect_(*DrawItem\hDC, *DrawItem\rcItem, Brush)
        DeleteObject_(Brush)
        SetTextColor_(*DrawItem\hDC, $FFFFFF)
      Else
        FillRect_(*DrawItem\hDC, *DrawItem\rcItem,
          GetStockObject_(#WHITE_BRUSH))
      EndIf

      If *DrawItem\itemID <> -1
        ItemText = Space(128)
        SendMessage_(*DrawItem\hwndItem, #CB_GETLBTEXT,
          *DrawItem\itemID, @ItemText)
        TextOut_(*DrawItem\hDC, *DrawItem\rcItem\left,
          *DrawItem\rcItem\top - 1, ItemText, Len(ItemText))
      EndIf
    EndIf
  EndIf

  ProcedureReturn Result
EndProcedure

Define i.I

OpenWindow(0, 200, 100, 230, 130, "ComboBoxGadget demo")
SetGadgetFont(#PB_Default, LoadFont(0, "Verdana", 10))
ComboBoxGadget(0, 10, 20, 100, 20)
ComboBoxGadget(1, 120, 20, 100, 20, #CBS_OWNERDRAWFIXED | #CBS_HASSTRINGS)

; ----- Interne Höhe des rechten ComboBoxGadgets erhöhen
SendMessage_(GadgetID(1), #CBEM_SETEXTENDEDSTYLE, 0, #CBES_EX_NOSIZELIMIT) 
SendMessage_(GadgetID(1), #CB_SETITEMHEIGHT, -1, 15)

SetWindowCallback(@WindowCallback())

For i = 1 To 5
  AddGadgetItem(0, -1, "Eintrag " + Str(i))
  AddGadgetItem(1, -1, "Eintrag " + Str(i))
Next

SetGadgetState(0, 0)
SetGadgetState(1, 0)
  
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
In diesem Fall könnten wahrscheinlich Experten aus dem englischen Forum (wie z.B. RASHAD) weiterhelfen. Wenn hier also nicht die perfekte Lösung gezeigt werden sollte, dann würde ich einfach dieses Problem einmal im englischen Forum vorstellen... :wink:

Kleine Änderung: Ich habe die Textfarbe eines Eintrages in der Ausklapp-Liste unter dem Cursor von Rot auf Weiss gesetzt, damit dies genauso aussieht wie bei der Auswahl in einer unveränderten ComboBox.
Zuletzt geändert von Shardik am 25.08.2018 07:35, insgesamt 1-mal geändert.
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: Comboboxgadget: Vertikale Ausrichtung des Inhalts

Beitrag von ccode_new »

@Shardik:

Das ist ein sehr schönes Beispiel.
Ich wusste auch noch nicht das man so etwas machen kann: #CBS_OWNERDRAWFIXED | #CBS_HASSTRINGS
Also den Text beibehalten.
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Benutzeravatar
techniker
Beiträge: 160
Registriert: 27.01.2016 11:08
Wohnort: BY

Re: Comboboxgadget: Vertikale Ausrichtung des Inhalts

Beitrag von techniker »

Habe das ganze etwas verfeinert - evtl. kann es ja jemand (zumindest als Anregung) gebrauchen.. :D

Code: Alles auswählen

DeclareModule Combo
  Enumeration ComboBoxGadgetPropertyType
    #CBG_Color_DefaultText
    #CBG_Color_DefaultBackground
    #CBG_Color_DropDownDefaultText
    #CBG_Color_DropDownDefaultBackground
    #CBG_Color_DropDownSelectedText
    #CBG_Color_DropDownSelectedBackground
    #CBG_VAlign
    #CBG_VAlign_Top
    #CBG_VAlign_Center
    #CBG_VAlign_Bottom
    #CBG_HAlign
    #CBG_HAlign_Left
    #CBG_HAlign_Center
    #CBG_HAlign_Right
  EndEnumeration
  
  Declare.l NewCBGadget(Gadget.i, x.l, y.l, Width.l, Height.l, Flags.l = 0)
  Declare SetProperty(Gadget.i, Type.a, Property.l)
  Declare Callback(result, hWnd, uMsg, wParam, lParam)
EndDeclareModule

Module Combo
  EnableExplicit
  
  #CBEM_SETEXTENDEDSTYLE = #WM_USER + 14
  #CBES_EX_NOSIZELIMIT = 8
  
  Structure CBG_Property_S
    DefaultTextColor.l
    DefaultBackgroundColor.l
    DropDownDefaultTextColor.l
    DropDownDefaultBackgroundColor.l
    DropDownSelectedTextColor.l
    DropDownSelectedBackgroundColor.l
    VAlign.l
    HAlign.l
  EndStructure
  
  NewMap CBG_Property.CBG_Property_S()
  
  Procedure.l NewCBGadget(Gadget.i, x.l, y.l, Width.l, Height.l, Flags.l = 0)
    Shared CBG_Property()
    Protected ret.l
    
    ret = ComboBoxGadget(Gadget, x, y, width, 1, Flags | #CBS_OWNERDRAWFIXED | #CBS_HASSTRINGS)
    If Gadget = #PB_Any : Gadget = ret : EndIf
    
    SendMessage_(GadgetID(Gadget), #CBEM_SETEXTENDEDSTYLE, 0, #CBES_EX_NOSIZELIMIT) 
    SendMessage_(GadgetID(Gadget), #CB_SETITEMHEIGHT, -1, Height - 5)
    
    If FindMapElement(CBG_Property(), Str(Gadget)) : DeleteMapElement(CBG_Property()) : EndIf
    AddMapElement(CBG_Property(), Str(Gadget))
    
    CBG_Property()\DefaultTextColor = #Black
    CBG_Property()\DefaultBackgroundColor = #White
    CBG_Property()\DropDownDefaultTextColor = #Black
    CBG_Property()\DropDownDefaultBackgroundColor = #White
    CBG_Property()\DropDownSelectedTextColor = #White
    CBG_Property()\DropDownSelectedBackgroundColor = RGB($1E, $90, $FF)
    CBG_Property()\VAlign = #CBG_VAlign_Top
    CBG_Property()\HAlign = #CBG_HAlign_Left
    
    ProcedureReturn ret
  EndProcedure
  
  
  Procedure SetProperty(Gadget.i, Type.a, Property.l)
    Shared CBG_Property()
    
    If IsGadget(Gadget) And FindMapElement(CBG_Property(), Str(Gadget))
      If Type = #CBG_Color_DefaultText : CBG_Property()\DefaultTextColor = Property
      ElseIf Type = #CBG_Color_DefaultBackground : CBG_Property()\DefaultBackgroundColor = Property
      ElseIf Type = #CBG_Color_DropDownDefaultText : CBG_Property()\DropDownDefaultTextColor = Property
      ElseIf Type = #CBG_Color_DropDownDefaultBackground : CBG_Property()\DropDownDefaultBackgroundColor = Property
      ElseIf Type = #CBG_Color_DropDownSelectedText : CBG_Property()\DropDownSelectedTextColor = Property
      ElseIf Type = #CBG_Color_DropDownSelectedBackground : CBG_Property()\DropDownSelectedBackgroundColor = Property
      ElseIf Type = #CBG_VAlign And Property = #CBG_VAlign_Top : CBG_Property()\VAlign = #CBG_VAlign_Top
      ElseIf Type = #CBG_VAlign And Property = #CBG_VAlign_Center : CBG_Property()\VAlign = #CBG_VAlign_Center
      ElseIf Type = #CBG_VAlign And Property = #CBG_VAlign_Bottom : CBG_Property()\VAlign = #CBG_VAlign_Bottom
      ElseIf Type = #CBG_HAlign And Property = #CBG_HAlign_Left : CBG_Property()\HAlign = #CBG_HAlign_Left
      ElseIf Type = #CBG_HAlign And Property = #CBG_HAlign_Center : CBG_Property()\HAlign = #CBG_HAlign_Center
      ElseIf Type = #CBG_HAlign And Property = #CBG_HAlign_Right : CBG_Property()\HAlign = #CBG_HAlign_Right
      EndIf
      
      SetGadgetState(Gadget, GetGadgetState(Gadget))
    EndIf
  EndProcedure
  
  
  Procedure Callback(result, hWnd, uMsg, wParam, lParam)
    Shared CBG_Property()
    Protected brush.i, *DrawItem.DRAWITEMSTRUCT, txt.s, dc.l, s.SIZE, px.l, py.l
    
    If FindMapElement(CBG_Property(), Str(wParam))
      If uMsg = #WM_DRAWITEM
        *DrawItem = lParam
    
        If *DrawItem\CtlType = #ODT_COMBOBOX
          SetBkMode_(*DrawItem\hDC, #TRANSPARENT)
    
          If *DrawItem\ItemState & #ODS_COMBOBOXEDIT
            ; Current choice
            brush = CreateSolidBrush_(CBG_Property()\DefaultBackgroundColor)
            FillRect_(*DrawItem\hDC, *DrawItem\rcItem, brush)
            DeleteObject_(brush)
            SetTextColor_(*DrawItem\hDC, CBG_Property()\DefaultTextColor)
          ElseIf *DrawItem\ItemState & #ODS_SELECTED
            ; Selected choice dropdown
            brush = CreateSolidBrush_(CBG_Property()\DropDownSelectedBackgroundColor)
            FillRect_(*DrawItem\hDC, *DrawItem\rcItem, brush)
            DeleteObject_(brush)
            SetTextColor_(*DrawItem\hDC, CBG_Property()\DropDownSelectedTextColor)
          Else
            ; Unselected choice dropdown
            brush = CreateSolidBrush_(CBG_Property()\DropDownDefaultBackgroundColor)
            FillRect_(*DrawItem\hDC, *DrawItem\rcItem, brush)
            DeleteObject_(brush)
            SetTextColor_(*DrawItem\hDC, CBG_Property()\DropDownDefaultTextColor)
          EndIf
          
          If *DrawItem\itemID <> -1
            txt = Space(1024)
            SendMessage_(*DrawItem\hwndItem, #CB_GETLBTEXT, *DrawItem\itemID, @txt)
            
            dc=GetDC_(hWnd)
            SelectObject_(dc, GadgetID(wParam))     
            GetTextExtentPoint32_(dc, @txt, Len(txt), s.SIZE)
            ReleaseDC_(GadgetID(wParam), dc)
            
            If CBG_Property()\VAlign = #CBG_VAlign_Bottom And *DrawItem\ItemState & #ODS_COMBOBOXEDIT
              py = *DrawItem\rcItem\top + (*DrawItem\rcItem\bottom - s\cy) - 3
            ElseIf CBG_Property()\VAlign = #CBG_VAlign_Center And *DrawItem\ItemState & #ODS_COMBOBOXEDIT
              py = *DrawItem\rcItem\top + (*DrawItem\rcItem\bottom - *DrawItem\rcItem\top - s\cy) / 2
            Else
              py = *DrawItem\rcItem\top
            EndIf
            
            If CBG_Property()\HAlign = #CBG_HAlign_Right And *DrawItem\ItemState & #ODS_COMBOBOXEDIT
              px = *DrawItem\rcItem\left + (*DrawItem\rcItem\right - s\cx) - 7
            ElseIf CBG_Property()\HAlign = #CBG_HAlign_Center And *DrawItem\ItemState & #ODS_COMBOBOXEDIT
              px = *DrawItem\rcItem\left + (*DrawItem\rcItem\right - *DrawItem\rcItem\left - s\cx) / 2
            Else
              px = *DrawItem\rcItem\left + 4
            EndIf
            
            TextOut_(*DrawItem\hDC, px, py, txt, Len(txt))
          EndIf
          
          result = #True
        EndIf
      EndIf
    EndIf
    ProcedureReturn result
  EndProcedure
  
EndModule




; ******************************************************************************************************
; Quick & Dirty Example  :-)
; ******************************************************************************************************


Procedure WindowCallback(hWnd, uMsg, wParam, lParam)
  Protected result.l = #PB_ProcessPureBasicEvents
  
  ; Callback für ComboBox aufrufen
  result = Combo::Callback(result, hWnd, uMsg, wParam, lParam)
  If result <> #PB_ProcessPureBasicEvents : ProcedureReturn result : EndIf
  
  ProcedureReturn result
EndProcedure

; --------------------

Define g.l, i.I

OpenWindow(0, 200, 100, 350, 130, "ComboBoxGadget demo")
SetGadgetFont(#PB_Default, LoadFont(0, "Verdana", 10))
ComboBoxGadget(0, 10, 20, 100, 20)
g = Combo::NewCBGadget(#PB_Any, 120, 20, 200, 50)

SetWindowCallback(@WindowCallback())

For i = 1 To 5
  AddGadgetItem(0, -1, "Eintrag " + Str(i))
  AddGadgetItem(g, -1, "Eintrag " + Str(i))
Next

SetGadgetState(0, 2)
SetGadgetState(g, 2)

combo::SetProperty(g, Combo::#CBG_Color_DropDownSelectedBackground, RGB(220,90,150))

Delay(2000)
combo::SetProperty(g, Combo::#CBG_Color_DefaultText, #Red)
combo::SetProperty(g, Combo::#CBG_VAlign, Combo::#CBG_VAlign_Center)
combo::SetProperty(g, Combo::#CBG_HAlign, Combo::#CBG_HAlign_Center)

Delay(2000)
combo::SetProperty(g, Combo::#CBG_Color_DefaultText, #Yellow)
combo::SetProperty(g, Combo::#CBG_Color_DefaultBackground, #Black)
combo::SetProperty(g, Combo::#CBG_VAlign, Combo::#CBG_VAlign_Bottom)
combo::SetProperty(g, Combo::#CBG_HAlign, Combo::#CBG_HAlign_Right)

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
Zuletzt geändert von techniker am 27.08.2018 19:55, insgesamt 1-mal geändert.
Never change a running system - Never run a changed system!
(PB 6.03 LTS [x86])
Benutzeravatar
mk-soft
Beiträge: 3700
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Comboboxgadget: Vertikale Ausrichtung des Inhalts

Beitrag von mk-soft »

Einfach unter Tools -> Strukturverzeichnis -> Konstanten -> CB_ nachschauen...
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Antworten