News:

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

Main Menu

Problems with OWNERDRAW menu

Started by xandaz, February 16, 2022, 04:12:36 AM

Previous topic - Next topic

xandaz

   Hi guys. I've dealing with this strange issue where the dwTypeData member appears empty. I'm posting the code so you can see what i'm doint wrong.    .elseif uMsg==WM_DRAWITEM
mov edi,lParam
assume edi:PTR DRAWITEMSTRUCT
invoke GetMenuItemInfoA,[edi].hwndItem,[edi].itemID,FALSE,addr tmii
invoke MessageBoxA,0,tmii.dwTypeData,0,MB_OK
invoke SHGetFileInfoA,tmii.dwItemData,0,addr shfi,sizeof shfi,SHGFI_SMALLICON
invoke SelectObject,[edi].hdc,shfi.hIcon
invoke DeleteObject,eax
invoke DrawIcon,[edi].hdc,[edi].rcItem.left,[edi].rcItem.top,shfi.hIcon
invoke DrawTextA,[edi].hdc,tmii.dwTypeData,-1,addr [edi].rcItem,DT_LEFT

xandaz

    After reading a bit od msdn information i found out that to retirieve the dwTypeData member of MENUITEMINFO there's little protocol for it, it's described in the following lines of code.  .elseif uMsg==WM_DRAWITEM
mov edi,lParam
assume edi:PTR DRAWITEMSTRUCT
mov tmii.dwTypeData,0
mov tmii.cch,0
invoke GetMenuItemInfoA,[edi].hwndItem,[edi].itemID,FALSE,addr tmii
inc tmii.cch
invoke LocalAlloc,LPTR,tmii.cch
mov tmii.dwTypeData,eax
invoke GetMenuItemInfoA,[edi].hwndItem,[edi].itemID,FALSE,addr tmii

Still the dwTypeData member appears empty. does MFT_STRING combine with MFT_OWNERDRAW? or can't they be mixed?

Greenhorn

You don't need to call GetMenuItemInfo in the WM_DRAWITEM.
If you've stored a pointer in dwItemData of the MENUITEMINFO structure (MIIM_DATA) you'll find it in the DRAWITEMSTRUCT member itemData.
Just have a look at the MSDN example for ownerdrawn menus.
Kole Feut un Nordenwind gift en krusen Büdel un en lütten Pint.

xandaz

   Hi Greenhorn. The problem is the dwTypeData member. It appears empty. Ty

Greenhorn

Did you stored a value in dwItemData ? You also have to set the corresponding flags in the fMask member of the MENUITEMINFO. What do you see in the itenData member of the DRAWITEMSTRUCT?
Did you had a look at the example on MSDN ?
Kole Feut un Nordenwind gift en krusen Büdel un en lütten Pint.

Greenhorn

Attached my old version of ownerdrawn menus.
Kole Feut un Nordenwind gift en krusen Büdel un en lütten Pint.

xandaz

   The menu looks terrific but the code is kinda complex. I'll see what I can get out of it. Thanks Greenhorn

xandaz

   Hi Guys. The following lines of cpde should work but dont. It's in accoordance with MSDN documentation. It gives invalid handle eorror. Can anyone tell me why?    .elseif uMsg==WM_DRAWITEM
mov edi,lParam
assume edi:PTR DRAWITEMSTRUCT
mov tmii.cbSize,sizeof MENUITEMINFO
mov tmii.fMask,MIIM_ID or MIIM_STRING or MIIM_TYPE OR MIIM_DATA
mov tmii.fType,MFT_STRING
mov tmii.dwTypeData,NULL
invoke GetMenuItemInfoA,[edi].hwndItem,[edi].itemID,FALSE,addr tmii
inc tmii.cch
invoke LocalAlloc,LPTR,tmii.cch
mov tmii.dwTypeData,eax
invoke GetMenuItemInfoA,[edi].hwndItem,[edi].itemID,FALSE,addr tmii
invoke DrawTextA,[edi].hdc,tmii.TypeData,-1,addr [edi].rcItem,DT_LEFT
mov eax,TRUE
ret

jj2007

It would be much easier to read with spaces after the comma:
GetMenuItemInfoA,[edi].hwndItem,[edi].itemID,FALSE,addr tmii
GetMenuItemInfoA, [edi].hwndItem, [edi].itemID, FALSE, addr tmii

So have you checked whether [edi].hwndItem has a valid value?

xandaz

   Yeah JJ. I've actually changed it to the original Menu Handle. Nothing seems to work. And i've tried to retrieve the dwItemData ( although its present in DRAWITEM Struct) and it worked. I've seen the same problem in StackOverflow and the solution presented is the same. Ty

TimoVJL

This C code is from working example:
void OnMeasureItem(HWND hwnd, MEASUREITEMSTRUCT * lpMeasureItem)
{
if (lpMeasureItem) {
// if (lpMeasureItem->itemHeight < 16)
// lpMeasureItem->itemHeight = 16;
lpMeasureItem->itemHeight = 24;
lpMeasureItem->itemWidth = 24;
}
return;
}

void OnDrawItem(HWND hwnd, const DRAWITEMSTRUCT * lpDrawItem)
{
if (lpDrawItem->CtlType == ODT_MENU) {
if (lpDrawItem->itemID < 10000) {
if (lpDrawItem->itemData) {
ImageList_Draw(g_hIml, lpDrawItem->itemData, lpDrawItem->hDC, 2, 2, ILD_NORMAL );
}
} else {
//FillRect(lpDrawItem->hDC, &lpDrawItem->rcItem, hBkBrush);
SetBkMode(lpDrawItem->hDC, TRANSPARENT);
char *p = (char*)lpDrawItem->itemData;
DrawText(lpDrawItem->hDC, (char*)lpDrawItem->itemData, -1, (RECT*)&lpDrawItem->rcItem, 0);
}
}
return;
}
May the source be with you

xandaz

    Sorry man. That doesn't help me much. ty anyway

TimoVJL

If we don't know what you are after, it's hard to help :sad:
May the source be with you

xandaz

#13
   Thanks all for help me out. Now i'm facing a new problem. Only the first dwTypeData gets Drawn.The other members of the menu seem to be overwritten by the others members. the code is as follows.    .elseif uMsg==WM_DRAWITEM
mov edi,lParam
assume edi:PTR DRAWITEMSTRUCT
.if [edi].itemAction==ODA_DRAWENTIRE
invoke Beep,1000,100
mov tmii.cbSize,sizeof MENUITEMINFO
mov tmii.fMask,MIIM_FTYPE or MIIM_ID or MIIM_STRING or MIIM_DATA
mov tmii.dwTypeData,0
mov tmii.cch,0
invoke GetMenuItemInfoA,[edi].hwndItem,[edi].itemID,FALSE,addr tmii
inc tmii.cch
invoke LocalAlloc,LPTR,tmii.cch
mov tmii.dwTypeData,eax
invoke GetMenuItemInfoA,[edi].hwndItem,[edi].itemID,FALSE,addr tmii
invoke DrawTextA,[edi].hdc,tmii.dwTypeData,-1,addr [edi].rcItem,DT_LEFT
mov eax,TRUE
ret
.endif

   The dwTypeData members seem to have a height that overfills the other members.

mikeburr

1) dont use assume .. you keep forgetting to assume nothing ...also its not compatible with 64 bit afaik shd you wish to convert later
2) i suspect the invoke ... API ...might well alter  edi .. you cd test this by displaying edi before and after .. i know quite a few of them do and esi
regards mike b