News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

OwnerDraw ComboBox

Started by ragdog, April 24, 2016, 11:27:21 PM

Previous topic - Next topic

ragdog

Hello all

I have a little problems with a Owner draw combobox
alle works fine but have this cbo a Focus or select a entry become i a white frame
How i can fill the white frame with a color or disable this.


fearless

Any code?

Prob respond to ODA_FOCUS i think and draw the roundrect (roundframe? cant remember which api - might be roundrect) like you have for the main box but with a whitebrush

ragdog

Hello Fearless

Here is my code but is not good enought i hope any can make it better or make a better look.


.if uMsg==WM_INITDIALOG
invoke CreateSolidBrush,BackGroundColor
mov hBackGroundColor ,eax

invoke CreateSolidBrush,FrameColor
mov hFrameColor,eax
invoke CreatePen,PS_INSIDEFRAME,1,FrameColor
mov PenFrameColor,eax

invoke GetDlgItem,hWnd,1001
mov hCbo ,eax

;subclass the combobox and ensure that the USERDATA still uses the old proc
invoke GetWindowLong, hCbo, GWL_WNDPROC
mov OldComboProc, eax
invoke SetWindowLong, hCbo, GWL_USERDATA, OldComboProc
invoke SetWindowLong, hCbo, GWL_WNDPROC, ComboProc


.elseif uMsg == WM_CTLCOLOREDIT
invoke CreateSolidBrush,BackGroundColor
ret
.elseif uMsg == WM_DRAWITEM
invoke OwnerDrawCbo,hWnd,lParam,BackGroundColor,FrameColor,0FFFFh

.elseif uMsg == WM_PAINT
invoke BeginPaint,hWnd,addr ps
mov ebx,eax
invoke DrawWindowColors,hWnd,ebx,BackGroundColor,0
invoke ReleaseDC,hWnd,ebx
invoke EndPaint,hWnd,addr ps
ret



wnerDrawCbo proc proc uses esi _hWnd:dword,_lparam:dword,_background_color:dword,_text_color:dword,_frame_color:dword
LOCAL rect:RECT
push esi
mov esi, _lparam
assume esi:ptr DRAWITEMSTRUCT
.if [esi].CtlType == ODT_COMBOBOX

.if [esi].itemState & ODS_SELECTED && [esi].itemState & ODA_SELECT;
invoke FillRect, [esi].hdc, addr [esi].rcItem, hBackGroundColor
invoke FrameRect, [esi].hdc, addr [esi].rcItem, hFrameColor

invoke SetBkMode, [esi].hdc, TRANSPARENT
invoke SetTextColor, [esi].hdc,_text_color

.elseif [esi].itemState & ODS_FOCUS
invoke FillRect, [esi].hdc, addr [esi].rcItem, hFrameColor
invoke FrameRect, [esi].hdc, addr [esi].rcItem, hFrameColor

invoke SetBkMode, [esi].hdc, TRANSPARENT
invoke SetTextColor, [esi].hdc,hBackGroundColor

.elseif [esi].itemState & ODS_COMBOBOXEDIT
invoke FillRect, [esi].hdc,addr [esi].rcItem,  hBackGroundColor
invoke FrameRect, [esi].hdc, addr [esi].rcItem,hFrameColor

invoke SetBkMode, [esi].hdc, TRANSPARENT
invoke SetTextColor, [esi].hdc,_text_color
.else
invoke FillRect, [esi].hdc, addr [esi].rcItem, hBackGroundColor
invoke SetBkMode, [esi].hdc, TRANSPARENT
invoke SetTextColor, [esi].hdc,_text_color
.endif
add [esi].rcItem.left,10
invoke DrawText, [esi].hdc, [esi].itemData, -1, addr [esi].rcItem, DT_LEFT or DT_VCENTER or DT_SINGLELINE
.endif
assume esi:nothing
pop esi
mov eax, TRUE
ret
OwnerDrawCbo endp

ComboProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
local rect:RECT
local rect2:RECT
local pt:POINT
local ps:PAINTSTRUCT
local hdc:HDC

.if uMsg == WM_PAINT
invoke SendMessage, hWnd, CB_GETCURSEL, 0, 0
push eax
invoke BeginPaint, hWnd, addr ps
mov hdc, eax

invoke GetClientRect, hWnd, addr rect
invoke InflateRect, addr rect, -1, -1
invoke GetSystemMetrics, SM_CXVSCROLL
sub rect.right, eax
invoke IntersectClipRect, hdc, rect.left, rect.top, rect.right, rect.bottom

invoke CallWindowProc, OldComboProc, hWnd, WM_PAINT, wParam, lParam

invoke SelectClipRgn, hdc, NULL
invoke GetSystemMetrics, SM_CXVSCROLL
add rect.right, eax
invoke ExcludeClipRect, hdc, rect.left, rect.top, rect.right, rect.bottom

invoke SelectObject,hdc,PenFrameColor

invoke SelectObject,hdc,hBackGroundColor
invoke FillRect,hdc,addr rect,ebx

;// now draw the button
invoke SelectClipRgn, hdc, NULL
invoke GetSystemMetrics, SM_CXVSCROLL
mov edx, rect.right
sub edx, eax
mov rect.left, edx
add rect.top,2
sub rect.bottom,2
invoke Rectangle, hdc, rect.left, rect.top, rect.right, rect.bottom;, 6, 6

pop eax
invoke SendMessage, hWnd, CB_SETCURSEL, eax, 0

invoke EndPaint, hWnd, addr ps

.elseif uMsg == WM_LBUTTONUP
.if fMouseDown
mov fMouseDown, FALSE
mov fButtonDown, FALSE
invoke InvalidateRect, hWnd, FALSE, FALSE
.endif

.elseif uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONDBLCLK
mov eax, lParam
movsx ebx, ax
mov pt.x, ebx
shr eax, 16
mov pt.y, eax
invoke GetClientRect, hWnd, addr rect
invoke InflateRect, addr rect, -1, -1
invoke GetSystemMetrics, SM_CXVSCROLL
mov edx, rect.right
sub edx, eax
mov rect.left, edx
invoke PtInRect, addr rect, pt.x, pt.y
.if eax
mov fMouseDown, TRUE
mov fButtonDown, TRUE
invoke InvalidateRect, hWnd, FALSE, FALSE
.endif

.elseif uMsg == WM_MOUSEMOVE
mov eax, lParam
movsx ebx, ax
mov pt.x, ebx
shr eax, 16
mov pt.y, eax
invoke GetClientRect, hWnd, addr rect
invoke InflateRect, addr rect, -1, -1
;invoke SetCursor, hCur
invoke PtInRect, addr rect, pt.x, pt.y
.if fButtonHover != eax
mov fButtonHover, eax
invoke InvalidateRect, hWnd,NULL,0
;invoke SetTimer, hWnd, 1, 10, NULL
.endif


.endif
invoke CallWindowProc, OldComboProc, hWnd, uMsg, wParam, lParam
ret
ComboProc endp




Thanks,

TouEnMasm

if this one can be of some help:
http://codes-sources.commentcamarche.net/source/15323-masm32-combobox-a-images-et-common-controls
Fa is a musical note to play with CL

ragdog

Thank you Yves but this is not what i want

My goal is a Complete Owner draw combobox with colors for frames ,Button etc,

fearless

looks pretty good so far, only came across this article that might help - its for .net stuff, but some of the ideas could be translated to win32/asm code perhaps:

http://www.codeproject.com/Tips/595936/Ownerdrawn-ComboBox-Example

couple things i did notice:
OwnerDrawCbo proc procprobably only needs one proc
and

.elseif [esi].itemState & ODS_FOCUS
invoke FillRect, [esi].hdc, addr [esi].rcItem, hFrameColor
invoke FrameRect, [esi].hdc, addr [esi].rcItem, hFrameColor

invoke SetBkMode, [esi].hdc, TRANSPARENT
invoke SetTextColor, [esi].hdc,hBackGroundColor
hBackground should probably be your _background_color parameter instead, otherwise sometimes the selected text shows up as a pink or other color (as its using a handle value instead of a color ref which _background_color would have)

and

.elseif uMsg == WM_CTLCOLOREDIT
invoke CreateSolidBrush,BackGroundColor

you can just return hBackgroundColor as you create this in the initdialog - saves you having to create and delete brushes - otherwise each time its called its creating another brush, so potentially a gdi leak?

But yes, comboboxes seem to be a real pain to control either by ownerdrawn or subclassing. Might be possible to create your own combobox control and control everything as its essentially a textbox, a button and a list control or maybe more control of each of the sub components might be useful using GetComboBoxInfo (https://msdn.microsoft.com/en-us/library/windows/desktop/bb775939%28v=vs.85%29.aspx) using the COMBOBOXINFO structure to get the handle to the editbox, the combo and the list control: (https://msdn.microsoft.com/en-us/library/windows/desktop/bb775798%28v=vs.85%29.aspx)

ragdog

Thank you FearLess

I have alle figured out and all works very fine now have i my Cbo finish post i my source.

I have a other Question How can a Draw a Arrow with Gdi

fearless

Id probably use the Theme parts for scrollbar itself:

OpenThemeData: https://msdn.microsoft.com/en-us/library/windows/desktop/bb759821%28v=vs.85%29.aspx

and using the Scrollbar parts (down arrows) https://msdn.microsoft.com/en-us/library/windows/desktop/bb773210%28v=vs.85%29.aspx

DrawThemeBackground: https://msdn.microsoft.com/en-us/library/windows/desktop/bb773289%28v=vs.85%29.aspx


include uxtheme.inc
includelib uxtheme.lib

.data
szwScrollbarTheme            DB "S",0,"C",0,"R",0,"O",0,"L",0,"L",0,"B",0,"A",0,"R",0,0,0,0,0

.data?
hThemeData                      DD ?

.code
Invoke OpenThemeData, hControl, Addr szwTreeviewClass
mov hThemeData, eax



then in wm_paint somewhere:

Invoke DrawThemeBackground, hThemeData, hdcMem, SBP_ARROWBTN, ABS_DOWNNORMAL, Addr rect, NULL ; or hdc if not using buffering.

Ive used that stuff to draw little + and - buttons that come from the treeview parts before in a property grid control i was working on:




.data
szwTreeviewPartsTheme            DB "T",0,"R",0,"E",0,"E",0,"V",0,"I",0,"E",0,"W",0,0,0,0

.code
Invoke OpenThemeData, hControl, Addr szwTreeviewPartsTheme
mov hThemeData, eax

Invoke DrawThemeBackground, hThemeData, hdcMem, TVP_GLYPH, GLPS_OPENED, Addr rect, NULL

Jochen_

Hello everyone ! :)

Are there code examples on the forum that show how to create an OwnerDraw ComboBox ?

thank you.

LiaoMi

Hi Jochen_,

welcome to the forum, there is a search function in the header, one more example below - How to Create an Owner-Drawn Combo Box https://docs.microsoft.com/en-us/windows/desktop/controls/create-an-owner-drawn-combo-box

Jochen_

oh .. and i see that it is with DialogProc & RES.
Just what i was looking for.:)
PS: I also want to draw the dropdown arrow on the combobox.

jj2007

Hi Jochen_,

There are two search functions:
- new forum
- old forum (lots of goodies!)

Welcome to the Forum :thup:

Jochen (no trailing understroke :smiley:)