LCF-AT Posted May 19, 2021 Share Posted May 19, 2021 Hi guys, just have a quick question about Listbox control and using some colors into them.Normaly I dont use OD for ListBox control but in this case it seems I have to use any.My goal is it just to color the background and specific text entrys I do send into the LB.All in all just 3 colors - Background, - TextColor Blue for normal logs / state (all ok) & TextColor Red for Error logs.So in normal case I color back / text at WM_CTLCOLORLISTBOX message but it seems I can not color the text entrys seperated... Info 1 <-- Blue Info 2 <-- Blue ErrorX <-- Red ....I get all blue or red only = Bad.Otherwise I dont wanna make any large OwnerDraw code just to create 2 diffrent text colors for normal & error logs you know.So is there a method I can send diffrent text colors without OD?If not how to do this again?I just forgot it already and can not find any example at the moment. DRAWITEMSTRUCT STRUCT CtlType DWORD ? CtlID DWORD ? itemID DWORD ? itemAction DWORD ? itemState DWORD ? hwndItem DWORD ? hdc DWORD ? rcItem RECT <> itemData DWORD ? DRAWITEMSTRUCT ENDS .elseif eax == WM_DRAWITEM mov edx, lParam .if [edx].DRAWITEMSTRUCT.CtlType == ODT_LISTBOX .endif Has anyone short example or template for the LB stuff?Somehow I dont get it work.Not sure anymore whether I have to use with Select functions here too.Thank you. greetz Link to comment
tonyweb Posted May 20, 2021 Share Posted May 20, 2021 (edited) Hello, waiting for experts I'll try to reply As far as I know you can't do that without owner-drawing. Owner drawing is basically the same you already used here: You need to handle both WM_MEASUREITEM and WM_DRAWITEM that will be called when you set the ownerdraw flag. You would need to select the needed font into your hDC (read SelectObject) and do the text measuring with, for example, GetTextExtentPoint32 and/or GetTextMetrics function. https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-gettextextentpoint32a Probably, going through your previous post, you would remember what is all about Check also the example here: https://docs.microsoft.com/de-de/windows/win32/controls/create-an-owner-drawn-list-box Best Regards, Tony Edited May 20, 2021 by tonyweb 1 Link to comment
LCF-AT Posted May 20, 2021 Author Share Posted May 20, 2021 Hi tonyweb, ok thanks but it looks again a little uhmmm you know.Just wanted ONLY to use 2 diffrent colors for the text lines I do send to the LB as I told before and that all.Dont wanna change any sizes or look of the default LB.Otherwise how to do that? invoke SendDlgItemMessage,hWnd,IDC_EDITLOG,LB_ADDSTRING,NULL,chr$("Test-String") invoke SendDlgItemMessage,hWnd,IDC_EDITLOG,WM_VSCROLL,SB_BOTTOM,NULL invoke SendDlgItemMessage,hWnd,IDC_EDITLOG,LB_ADDSTRING,NULL,chr$("Test-Error") invoke SendDlgItemMessage,hWnd,IDC_EDITLOG,WM_VSCROLL,SB_BOTTOM,NULL The normal strings I wanna log in color A (Blue) = default and all others with "Error" in the string I wanna log in Red color so that the user can see it quickly that something did fail.Simple thing right.Problem is that I can manage that on WM_CTLCOLORLISTBOX message so there I can just set one color only for entire LB each time = 💩 and how its going when I do use OD code stuff?Have I then always check all logged entrys for the Error string and color them?Sounds also bad somehow. My thing I wanna do (2 colors text) is so simple but the implementation is always such a PITA. greetz Link to comment
LCF-AT Posted May 20, 2021 Author Share Posted May 20, 2021 Hi again, ok I was playing around and made some code like this....so far... .elseif eax == WM_DRAWITEM mov edi, lParam ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; .if [edi].DRAWITEMSTRUCT.CtlType == ODT_LISTBOX .if [edi].DRAWITEMSTRUCT.itemID != -1h ; nothing .if [edi].DRAWITEMSTRUCT.itemAction == ODA_DRAWENTIRE invoke FillRect,[edi].DRAWITEMSTRUCT.hdc,addr [edi].DRAWITEMSTRUCT.rcItem,GSC ; brush color .elseif [edi].DRAWITEMSTRUCT.itemAction == ODA_SELECT .elseif [edi].DRAWITEMSTRUCT.itemAction == ODA_FOCUS .endif invoke SendMessage,[edi].DRAWITEMSTRUCT.hwndItem,LB_GETTEXTLEN,[edi].DRAWITEMSTRUCT.itemID,NULL .if eax > NULL invoke SendMessage,[edi].DRAWITEMSTRUCT.hwndItem,LB_GETTEXT,[edi].DRAWITEMSTRUCT.itemID,addr _LBBUFFER .if eax > NULL lea esi, _LBBUFFER mov esi, [esi] invoke lenA,esi invoke TextOut,[edi].DRAWITEMSTRUCT.hdc,[edi].DRAWITEMSTRUCT.rcItem.left,[edi].DRAWITEMSTRUCT.rcItem.top,esi, eax .endif .endif .endif .endif MOV EAX,TRUE ret ...somehow its not working correctly with my code above.The ODA_DRAWENTIRE does not draw the whole background only the background of logged strings.Also on TextOut function it does fill the entire LB with the same strings which I have logged as last!?The text color is also looking smudged / unclean / bold etc.Can anyone edit my code example to fix the wrong parts of me? greetz Link to comment
tonyweb Posted May 21, 2021 Share Posted May 21, 2021 (edited) Hi @LCF-AT, still trying to help waiting for "real" guys Quote The ODA_DRAWENTIRE does not draw the whole background only the background of logged strings. This may be related to how you handle the MEASUREITEM event message. Try to take inspiration from this code, taken from CodeProject: all credits to the author, of course! // Source: https://www.codeproject.com/Articles/135855/Owner-Drawn-CListBox void CMultiLineListBox::AppendString(LPCSTR lpszText, COLORREF fgColor, COLORREF bgColor) { LISTBOX_COLOR* pInfo = new LISTBOX_COLOR; pInfo->strText.Format(_T("%s"), lpszText); pInfo->fgColor = fgColor; pInfo->bgColor = bgColor; SetItemDataPtr(AddString(pInfo->strText), pInfo); // LB_SETITEMDATA, LB_ADDSTRING (SendMessage) } void CMultiLineListBox::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct) { // TODO: Add your code to determine the size of specified item ASSERT(lpMeasureItemStruct->CtlType == ODT_LISTBOX); CString strText(_T("")); GetText(lpMeasureItemStruct->itemID, strText); ASSERT(TRUE != strText.IsEmpty()); CRect rect; GetItemRect(lpMeasureItemStruct->itemID, &rect); CDC* pDC = GetDC(); lpMeasureItemStruct->itemHeight = pDC->DrawText(strText, -1, rect, DT_WORDBREAK | DT_CALCRECT); ReleaseDC(pDC); } void CMultiLineListBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { // TODO: Add your code to draw the specified item ASSERT(lpDrawItemStruct->CtlType == ODT_LISTBOX); LISTBOX_COLOR* pListBox = (LISTBOX_COLOR*)GetItemDataPtr(lpDrawItemStruct->itemID); // // LB_GETITEMDATA (SendMessage) ASSERT(NULL != pListBox); CDC dc; dc.Attach(lpDrawItemStruct->hDC); // Save these value to restore them when done drawing. COLORREF crOldTextColor = dc.GetTextColor(); COLORREF crOldBkColor = dc.GetBkColor(); // If this item is selected, set the background color // and the text color to appropriate values. Also, erase // rect by filling it with the background color. if ((lpDrawItemStruct->itemAction | ODA_SELECT) && (lpDrawItemStruct->itemState & ODS_SELECTED)) { dc.SetTextColor(pListBox->bgColor); dc.SetBkColor(pListBox->fgColor); dc.FillSolidRect(&lpDrawItemStruct->rcItem, pListBox->fgColor); } else { dc.SetTextColor(pListBox->fgColor); dc.SetBkColor(pListBox->bgColor); dc.FillSolidRect(&lpDrawItemStruct->rcItem, pListBox->bgColor); } lpDrawItemStruct->rcItem.left += 5; // Draw the text. dc.DrawText(pListBox->strText, pListBox->strText.GetLength(), &lpDrawItemStruct->rcItem, DT_WORDBREAK); // Reset the background color and the text color back to their // original values. dc.SetTextColor(crOldTextColor); dc.SetBkColor(crOldBkColor); dc.Detach(); } I chose to compile it and attach it here, so you can see the code at assembly level (you're very familiar with, see RVA: 1FD0). Demo.zip Don't know if it's completely okay to attach: it should be, cause we're giving proper credts So again, this is simply compiled from : https://www.codeproject.com/Articles/135855/Owner-Drawn-CListBox I changed a bit the code to have some blue and one red string only (even if I changed only the "main" code): Demo_Modded.zip Hope this helps a bit. Best Regards, Tony Edited May 21, 2021 by tonyweb Replaced with a /MT compiled executable, Demo modded, some remarks for ItemData 2 Link to comment
LCF-AT Posted May 21, 2021 Author Share Posted May 21, 2021 Hi Tony, thanks for that infos / examples but I don't get it work correctly in my case. I also get always just the same logged text into the LB to too.If I send 3 diffrent text lines then all getting same in the entire LB.Somehow it sucks again.By the way, I am using a LB from resources with enabled style LBS_OWNERDRAWFIXED. What about the whole LB background (which is empty)?I can not color that?Only background of logged text? greetz Link to comment
Teddy Rogers Posted May 22, 2021 Share Posted May 22, 2021 What about adding an icon before the text to indicate what it is you want the user to know? Ted. 1 Link to comment
fearless Posted May 22, 2021 Share Posted May 22, 2021 Probably easier to use a listview with customdraw handling and you can assign text color based on some condition stored in lparam - pointer to a structure for each item that contains a type (so you can color code accordingly) or just use lparam as the 'type' value. 0 normal, 1 cool blue, 2 red, 3 something else etc. 1 Link to comment
LCF-AT Posted May 22, 2021 Author Share Posted May 22, 2021 Hi guys, sure I could use a LV where I have more infos about and examples but I wanna also know how to deal with LBs too.At the moment I try to create a example project just using a LB from resources and doing some WM_DRAWITTEM handling.Now I have some diffrent questions. Which messages I have to catch / handle for a ListBox at WM_DRAWITTEM?In my case I just get the itemActions only and NO itemStates!Why?See my new code below.... CONTROL "",IDC_LISTBOX,"ListBox",0x50010150,17,9,354,74,0x00000200 .elseif eax == WM_DRAWITEM mov edi, lParam assume edi: ptr DRAWITEMSTRUCT .if [edi].CtlType == ODT_LISTBOX .if [edi].itemID != -1 .if [edi].CtlID == IDC_LISTBOX .if [edi].itemAction == ODA_DRAWENTIRE invoke FillRect,[edi].hdc,addr [edi].rcItem,GSC ; brush color yellow invoke SetTextColor,[edi].hdc,Blue .elseif [edi].itemAction == ODA_SELECT invoke SetTextColor,[edi].hdc,Red ; invoke FillRect,[edi].hdc,addr [edi].rcItem,GSC2 ; brush color gray .elseif [edi].itemAction == ODA_FOCUS invoke SetTextColor,[edi].hdc,Red invoke FillRect,[edi].hdc,addr [edi].rcItem,GSC2 ; brush color gray .endif invoke SendMessage,[edi].hwndItem,LB_GETTEXT,[edi].itemID,addr _LBBUFFER mov ecx, eax invoke DrawText,[edi].hdc,addr _LBBUFFER,ecx,addr [edi].rcItem,DT_WORDBREAK .if [edi].itemState == ODS_DEFAULT exit .elseif [edi].itemState == ODS_SELECTED exit .elseif [edi].itemState == ODS_DISABLED exit .elseif [edi].itemState == ODS_FOCUS exit .endif .endif .endif .endif assume edi: nothing ....I get nothing on itemstate check = no exit call.In the LB I have pushed some strings.Somehow it looks not so good.Has nobody a already done template for that etc? ....so when I have to fill the background of item?On every message of itemAction?The second entry I have selected and the line is gray but the background of text is still yellow a little.Not sure why its mixed here.The visible LB emty box is white so this sucks.Why I can not color this too?In default mode I get also the whole LB background colored at WM_CTLCOLORLISTBOX color for listbox message. @fearless Do you have not any template laying around somewhere for that OD LB?Just need to know what to catch / handle and where to draw etc you know. @Teddy Rogers Sure, a Icon before would be also nice.Main goal was it for me just to log the strings into 2 diffrent colors (specially RED color for Error logs) so that the user can see it quickly.Other having a whole OD template for a entire LB (example) would also be nice. greetz 1 Link to comment
LCF-AT Posted May 23, 2021 Author Share Posted May 23, 2021 Hi again, so I did debug that struct in Olly now and I see some issues by checking the itemState.So the struct is this..... DRAWITEMSTRUCT STRUCT CtlType DWORD ? CtlID DWORD ? itemID DWORD ? itemAction DWORD ? itemState DWORD ? hwndItem DWORD ? hdc DWORD ? rcItem RECT <> itemData DWORD ? DRAWITEMSTRUCT ENDS or on MSDN = typedef struct tagDRAWITEMSTRUCT { UINT CtlType; UINT CtlID; UINT itemID; UINT itemAction; UINT itemState; HWND hwndItem; HDC hDC; RECT rcItem; ULONG_PTR itemData; } DRAWITEMSTRUCT, *PDRAWITEMSTRUCT, *LPDRAWITEMSTRUCT; As you can see all paramters holding a DWORD lenght typedef (itemAction / itemState).In that case I should check the itemAction / itsemState with a DWORD but its not working for the itemState!Lets have a look in Olly... ODT_MENU equ 1 ODT_LISTBOX equ 2 ODT_COMBOBOX equ 3 ODT_BUTTON equ 4 ODT_STATIC equ 5 ODA_DRAWENTIRE equ 1h ODA_SELECT equ 2h ODA_FOCUS equ 4h ODS_SELECTED equ 1h ODS_GRAYED equ 2h ODS_DISABLED equ 4h ODS_CHECKED equ 8h ODS_FOCUS equ 10h ODS_DEFAULT equ 20h ODS_COMBOBOXEDIT equ 1000h ODS_HOTLIGHT equ 40h ODS_INACTIVE equ 80h $ ==> 012FF0CC <CtlType> 00000002 $+4 012FF0D0 <CtlID> 000003E8 $+8 012FF0D4 <itemID> 00000001 $+C 012FF0D8 <itemAction> 00000002 <-- ODA_SELECT $+10 012FF0DC <itemState> 00000301 <-- ODS_SELECTED byte 01 $+14 012FF0E0 <hwndItem> 00090846 $+18 012FF0E4 <hdc> A60111B4 $+1C 012FF0E8 <rcItem.left> 00000000 $+20 012FF0EC <rcItem.top> 00000010 $+24 012FF0F0 <rcItem.right> 000001C7 $+28 012FF0F4 <rcItem.bottom> 00000020 $+2C 012FF0F8 <itemData> 0344AB60 My code by checking the state seperated does fail .if [edi].itemState == ODS_DEFAULT exit .elseif [edi].itemState == ODS_SELECTED exit .elseif [edi].itemState == ODS_DISABLED exit .elseif [edi].itemState == ODS_FOCUS exit .endif So I can change it by adding byte ptr onto .elseif byte ptr [edi].itemState == ODS_SELECTED ; Seems to work. Now lets check again your code @tonyweb you did post above... if ((lpDrawItemStruct->itemAction | ODA_SELECT) && (lpDrawItemStruct->itemState & ODS_SELECTED)) ...you do check itemAction for ODA_SELECT & itemState for ODS_SELECTED together but your code in Olly dosen't check the DWORDs... 003C1F43 |. 8B4F 0C MOV ECX,DWORD PTR DS:[EDI+C] ; itsemAction DWORD to ecx 003C1F46 |. 83C9 02 OR ECX,2 ; or ecx 2 why? 003C1F49 |. 8945 08 MOV DWORD PTR SS:[EBP+8],EAX 003C1F4C |. 74 23 JE SHORT 003C1F71 003C1F4E |. F647 10 01 TEST BYTE PTR DS:[EDI+10],1 ; Test byte edi+10 = itsemState 003C1F52 |. 74 1D JE SHORT 003C1F71 So if I do use that command style like you do =...... .elseif [edi].itemAction == ODA_SELECT && [edi].itemState == ODS_SELECTED ...then its looking so in Olly... 0116F62C <CtlType> 00000002 0116F630 <CtlID> 000003EA 0116F634 <itemID> 00000000 0116F638 <itemAction> 00000002 <-- 0116F63C <itemState> 00000301 <-- 0116F640 <hwndItem> 00020A4A 0116F644 <hdc> CA011544 0116F648 <rcItem.left> 00000000 0116F64C <rcItem.top> 00000000 0116F650 <rcItem.right> 0000020F 0116F654 <rcItem.bottom> 00000010 0116F658 <itemData> 00000000 00881327 > \837F 0C 02 CMP DWORD PTR DS:[EDI+C],2 ; itsemAction 0088132B . 75 38 JNZ SHORT 00881365 0088132D . 837F 10 01 CMP DWORD PTR DS:[EDI+10],1 ; itsemState 00881331 . 75 32 JNZ SHORT 00881365 Exit <--- Never reached Its not checking the same way in my case.Only can change it by checking the byte directly itself.... .elseif [edi].itemAction == ODA_SELECT && byte ptr [edi].itemState == ODS_SELECTED ...then it seems to work.Somehow strange that the struct for itemState is declared as DWORD but not working to check it as DWORD or UINT (typedef DWORD) which is also DWORD.So whats the problem in this case?Is it me again to understand something not correctly or am I right and MSDN did some fail?Its pretty bad that I get sometimes such strange errors / something not working like it works for you & others you know.Just because of such issues.Maybe anyone can explain it to me. greetz 1 Link to comment
kao Posted May 23, 2021 Share Posted May 23, 2021 1 hour ago, LCF-AT said: Is it me again to understand something not correctly You just didn't read MSDN properly. See https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-drawitemstruct (emphasis mine): Quote itemState Type: UINT The visual state of the item after the current drawing action takes place. This member can be a combination of the values shown in the following table. Value 0x301 decodes as ODS_NOFOCUSRECT | ODS_NOACCEL | ODS_SELECTED. The correct way for checking such flags is by using "and" or "test" operation, just like Tonyweb's code does. Your code comparing byte value will fail, for example, on flags ODS_DEFAULT | ODS_SELECTED or anything like that.. 3 Link to comment
LCF-AT Posted May 23, 2021 Author Share Posted May 23, 2021 Hi, hhmm.But on itemAction you can read same too (This member can be one or more of the values).Otherwise if I use DRAWITEMSTRUCT for buttons I can check all seperated.That again really confusing.So if the command by Tony is right.... if ((lpDrawItemStruct->itemAction | ODA_SELECT) && (lpDrawItemStruct->itemState & ODS_SELECTED)) ....how should it look for me then in MASM using high syntax commands... .if [edi].itemAction == ODA_SELECT && [edi].itemState == ODS_SELECTED = ?? greetz 1 Link to comment
fearless Posted May 24, 2021 Share Posted May 24, 2021 If you only want to process if action is select and state is selected then something like: mov eax, [edi].itemState and eax, ODS_SELECTED mov ebx, [edi].ItemAction and ebx, ODA_SELECT .IF eax == ODS_SELECTED && ebx == ODA_SELECT 1 Link to comment
LCF-AT Posted May 24, 2021 Author Share Posted May 24, 2021 Hi, so that what I don't wanna do fearless.Using manually register moves / and operation (looks total bad adding that extra code).Just wanted to write it directly at once but seems not to work with MASM as on C or C++ like Tony did.There you also see no extra moves you know. So what is if I do it like you postet fearless.How should the entire template look like?What if I need or have to check more than one itemState etc? What is if I wanna check every single itemState one by one?How should that look please!Like dirt!Maybe like this...? mov eax, [edi].itemState and eax, ODS_SELECTED .if eax == ODS_SELECTED nop .else mov eax, [edi].itemState and eax, ODS_DEFAULT .if eax == ODS_DEFAULT nop .else mov eax, [edi].itemState and eax, ODS_FOCUS .if eax == ODS_FOCUS nop .else nop .endif .endif .endif Ah come on!You can't be seroius or?How to manage that checks if I have a LOT to check?There are 11 itsemStates conditions which could happen and can be checked (also if there are not all for a LB).Sorry fearless, but this method is total bad.Is there no special macro we can use?Otherwise to write in such a style is also messy and my goal was it to write codes clean and clear you know.How would you do write the code with few more checks (3-5 etc)? greetz Link to comment
LCF-AT Posted May 24, 2021 Author Share Posted May 24, 2021 Hi again, so what about using switch & case commands? switch [edi].DRAWITEMSTRUCT.itemState case ODS_SELECTED nop case ODS_DEFAULT nop case ODS_FOCUS nop default nop nop endsw Where to set a "and" operation for EAX?How to manage that in this example? Example of code I found....of C or C++ etc. http://cplusplus.com/forum/windows/14130/#msg69044 case ODA_DRAWENTIRE: if (lpDStruct->itemState & ODS_SELECTED) { DrawSelected(lpDStruct); } else { DrawEntire(lpDStruct); } break; case ODA_FOCUS: DrawFocused(lpDStruct); break; case ODA_SELECT: //DrawSelected(lpDStruct); if (lpDStruct->itemState & ODS_SELECTED) { DrawSelected(lpDStruct); } else { DrawEntire(lpDStruct); } break; default: break; Does it mean at the end that I can forget it to check such flags / combinations similar like above for C / C++ and that I HAVE to do some and / or extra ASM commands stuff and blowing up the whole code with if/else/endif statements between?Just asking only of course. greetz Link to comment
LCF-AT Posted May 25, 2021 Author Share Posted May 25, 2021 Hi again, still need some help and info how to check the flags & combined flag combos.Just check it for listbox...just can check one by one but how if they combined?That really makes me sick and the checks are looking like crap!Some better infos / hints are welcome if you got any. .elseif eax == WM_DRAWITEM mov edi, lParam assume edi: ptr DRAWITEMSTRUCT .if [edi].CtlType == ODT_BUTTON .elseif [edi].CtlType == ODT_COMBOBOX .if [edi].itemID == -1 ; no items nop ; draw only the focus rectangle .else .endif .elseif [edi].CtlType == ODT_LISTBOX .if [edi].itemID == -1 ; no items nop ; draw only the focus rectangle .else .if [edi].CtlID == IDC_LISTBOX ; optional check for ID equ of control .if [edi].itemAction == ODA_DRAWENTIRE mov eax, [edi].DRAWITEMSTRUCT.itemState and eax, ODS_SELECTED .if eax == ODS_SELECTED nop .else mov eax, [edi].DRAWITEMSTRUCT.itemState and eax, ODS_FOCUS .if eax == ODS_FOCUS nop .else mov eax, [edi].DRAWITEMSTRUCT.itemState and eax, ODS_DEFAULT .if eax == ODS_DEFAULT nop .else mov eax, [edi].DRAWITEMSTRUCT.itemState and eax, ODS_DISABLED .if eax == ODS_DISABLED nop .endif .endif .endif .endif .endif .endif .endif .elseif [edi].CtlType == ODT_LISTVIEW .elseif [edi].CtlType == ODT_MENU .elseif [edi].CtlType == ODT_STATIC .elseif [edi].CtlType == ODT_TAB .endif assume edi: nothing greetz Link to comment
kao Posted May 25, 2021 Share Posted May 25, 2021 (edited) There is no need to do IF cases for things you do not support. It takes up a lot of space and gives you zero value. So, I would get rid of those immediately. As for the rest: On 5/24/2021 at 1:06 AM, kao said: The correct way for checking such flags is by using "and" or "test" operation, just like Tonyweb's code does. Here are few options how I would write such code. It's a matter of personal preference, every coder has his/her personal style. * jump-style. This is my personal favorite, as it's the closest to the actual assembly code: test [edi].DRAWITEMSTRUCT.itemState, ODS_DEFAULT jz notODS_DEFAULT ; process ODS_DEFAULT nop jmp afterItemState notODS_DEFAULT: test [edi].DRAWITEMSTRUCT.itemState, ODS_SELECTED jz notODS_SELECTED ; process ODS_SELECTED nop jmp afterItemState notODS_SELECTED: test [edi].DRAWITEMSTRUCT.itemState, ODS_FOCUS jz afterItemState ; process ODS_FOCUS nop ; fallthrough, so no jump here afterItemState: * .if style. It looks closer to C code and generates the exact same assembly code as above. I'm not a fan of this but if you like it, why not.. .if [edi].DRAWITEMSTRUCT.itemState & ODS_DEFAULT ; process ODS_DEFAULT nop .elseif [edi].DRAWITEMSTRUCT.itemState & ODS_SELECTED ; process ODS_SELECTED nop .elseif [edi].DRAWITEMSTRUCT.itemState & ODS_FOCUS ; process ODS_FOCUS nop .endif EDIT: depending on what you want to do, you might need to replace ".elseif" with ".endif" + another ".if". My point was to show a method how to test bitflags, nothing else. Edited May 25, 2021 by kao 1 Link to comment
LCF-AT Posted May 25, 2021 Author Share Posted May 25, 2021 Hi kao, thanks for trying to help but I see your code examples are looking similar bad as my with If / Endif commands.Its maybe ok to check single statement flags one by one but what about flag combos?How to check them? Lets say there are 10 possible diffrent flags a state can have.10 single diffrent states = Ok alright so that possible to check one by one.Now lets say the state can also be a combo of max 6 flags so how to find out / check them?Do you know what I mean?Its just crazy. Question: Just in the example of a LISTBOX lets try to find out what I need to know to create a 100% right working OwnerDraw template for WM_DRAWITTEM.First I need to check for CtlType which can be... The control type. This member can be one of the following values. See Remarks. ODT_BUTTON ODT_COMBOBOX ODT_LISTBOX ODT_LISTVIEW ODT_MENU ODT_STATIC ODT_TAB Remarks Some control types, such as status bars, do not set the value of CtlType ...MSDN tells me that only one control member can be inside of CtlType I have to check for.Ok, lets check next important one itemAction... The required drawing action. This member can be one or more of the values. ODA_DRAWENTIRE ODA_FOCUS ODA_SELECT ....Ohhhh, that member can be ONE or MORE!?Danger!You have to make a ONE or MORE checking code right!WHat does it mean?It can be just one by one = checking just the DWORD itsemAction for one of them OR what can it be else? ODA_DRAWENTIRE + ODA_FOCUS + ODA_SELECT ODA_DRAWENTIRE + ODA_FOCUS ODA_DRAWENTIRE + ODA_SELECT etc.... Now the itemState.... The visual state of the item after the current drawing action takes place. This member can be a combination of the values shown in the following table. ODS_CHECKED This bit is used only in a menu. ODS_COMBOBOXEDIT Just owner-drawn for combo box. ODS_DEFAULT The item is the default item. <--- What does that mean? ODS_DISABLED The item is to be drawn as disabled. ODS_FOCUS The item has the keyboard focus. ODS_GRAYED The item is to be grayed. This bit is used only in a menu. ODS_HOTLIGHT The item is being hot-tracked, that is, the item will be highlighted when the mouse is on the item. ODS_INACTIVE The item is inactive and the window associated with the menu is inactive. ODS_NOACCEL The control is drawn without the keyboard accelerator cues. ODS_NOFOCUSRECT The control is drawn without focus indicator cues. ODS_SELECTED The menu item's status is selected. What I have to check for an LISTBOX = All except ODS_CHECKED, ODS_COMBOBOXEDIT, ODS_GRAYED...right?There are 11 diffrent flags minus 3 flags = 8 flags left to check in the case of a LISTBOX..right?Now I would like to know how a really smart checking template would look like to handle ALL diffrent cases / combinations.Sorry, maybe I do think again in a wrong direction or my logical thinking is on vacation but somehow I don't get smarter by trying to handle all those diffrent situations without to write tons of code checkings you know.Otherwise I also have to find out which flag combinations are possible....so there I see no information on MSDN.As I said, I'am maybe just too un-smart for that to get any good checking solution in my head or whatever the reason.If possible then it would be nice if someone could example it to me HOW I have/must understand that DRAWITEMSTRUCT + handling at WM_DRAWITTEM message. greetz Link to comment
LCF-AT Posted May 26, 2021 Author Share Posted May 26, 2021 Hi, just another small AddOn question.Is there anywhere a list to find about the themes I can use with the SetWindowTheme function and which controls getting be affected etc?The description of that function is again pretty small and the example does just show one info... Examples The following example code gives a list-view control the appearance of a Windows Explorer list: SetWindowTheme(hwndList, L"Explorer", NULL); ...so I'am using this for my listviews but what about LixtBoxes?Seems that this is not working for it.I would like to give my Listbox the same look / selecting style as for my listview you know.Is that also possible or not? greetz Link to comment
LCF-AT Posted May 28, 2021 Author Share Posted May 28, 2021 Hi again, does anyone know any good complete tutorial/s about OwnerDraws for all controls?Anyway if in C++ or other languages etc. I also wanna know where I can find a complete list of all controls & classes I can use.I found something here... https://docs.microsoft.com/en-us/windows/win32/winauto/uiauto-controlsupport ...just wanna know whether they are more and if yes I need the names & description etc. I also wanna know what kind of intern ready controls I can use.Something like the color controls to pick colors (dont know the class / control name of it) or the explorer Window to load / save files etc you know what I mean right.Just wanna get / create a list of everything I can already use (nothing I need to create by myself later) if I need any of them.Maybe you can help with that a little.Thank you. PS: Still wanna know what flag conditions I have to check for my ListBox I did post above or for any other controls.Any infos would be welcome before trying all out manually. greetz Link to comment
kao Posted May 30, 2021 Share Posted May 30, 2021 Controls & Dialogs - are you looking for something like this? https://docs.microsoft.com/en-us/windows/win32/controls/individual-control-info https://docs.microsoft.com/en-us/windows/win32/dlgbox/dialog-box-types As for the listbox, I did my best to explain it to you. If you still don't understand it, I've obviously failed - but there's nothing else I can do about that. 2 Link to comment
LCF-AT Posted May 30, 2021 Author Share Posted May 30, 2021 Hi kao, thanks for the new links, thats what I was looking for.Just wanna ask whether that all or are there some more etc? About my Listbox OD problem.So I'am always happy to get some help for my questions you know.In the cases of itemAction & itsemState its still hard for me to find any description about a complete OD (of LB in this case) which does handle really ALL possible conditions but for this I need to find out what conditions can be hit together as I told above.Maybe its important to know if someone wants to create extra OD for every single case.Otherwise I'am thinking maybe again in a wrong direction or whatever it is again.Maybe I should just care about the minimum important flags only.Will see. greetz Link to comment
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now