All Things WinBatch > WinBatch

Image in menu bar

(1/5) > >>

erezpaz:
Hi

I wonder if there is a way to insert a small image in the left side before text in the menu-bar dynamic dialog. Something like the attached.

Thanks

td:
It is theoretically possible using DllCall but the process is a bit convoluted, may not actually work, and hardly seem worth the effort.

erezpaz:
Can you give me more details or point me where can I read about it? Thanks!!

td:
Here is an embarrassingly poorly written script that demonstrates the basics while managing to do nothing particularly useful.


--- Code: Winbatch ---;; Define UDFs.
gosub defineudps

MenuBitmapFormat=`WWWDLGED,6.2`

MenuBitmapCaption=`WIL Dialog 1`
MenuBitmapX=001
MenuBitmapY=001
MenuBitmapWidth=352
MenuBitmapHeight=241
MenuBitmapNumControls=005
MenuBitmapProcedure=`MenuBitmapProc`
MenuBitmapFont=`DEFAULT`
MenuBitmapTextColor=`DEFAULT`
MenuBitmapBackground=`DEFAULT,DEFAULT`
MenuBitmapConfig=0

MenuBitmap001=`095,226,032,011,PUSHBUTTON,"PushButton_OK",DEFAULT,"OK",1,10,@csDefButton,DEFAULT,DEFAULT,DEFAULT`
MenuBitmap002=`223,226,032,011,PUSHBUTTON,"PushButton_Cancel",DEFAULT,"Cancel",0,20,DEFAULT,DEFAULT,DEFAULT,DEFAULT`
MenuBitmap003=`000,000,000,000,MENUBAR,"Dialog_Bar"`
MenuBitmap004=`000,000,000,000,MENUITEM,"mbi1_MyDialog","Dialog_Bar","Bitmap",DEFAULT,10,DEFAULT`
MenuBitmap005=`000,000,000,000,MENUITEM,"mbi2_MenuBitmap","mbi1_MyDialog","Has One",DEFAULT,10,DEFAULT`

ButtonPushed=Dialog("MenuBitmap")

exit

:defineudps

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Simple way to create a dummy menu item bitmap for testing
;; purposes.
;;
;; Returns a Windows bitmap handle.
#definefunction CreateMenuBitmap()
    hUser32 = DllLoad('user32.dll')

    hwndDesktop = DllCall(hUser32, long:'GetDesktopWindow')
    hdcDesktop = DllCall(hUser32, long:'GetDC', long:hwndDesktop)
 
    ; Determine the required bitmap size.
    SM_CXMENUCHECK = 71
    SM_CYMENUCHECK = 72
    nX = WinMetrics(SM_CXMENUCHECK)
    nY = WinMetrics(SM_CYMENUCHECK)
 
    ; Create a monochrome bitmap and select it.
    hGdi32 = DllLoad('Gdi32.dll')
    hdcMem = DllCall(hGdi32, long:'CreateCompatibleDC', long:hdcDesktop)
    hbm = DllCall(hGdi32, long:'CreateBitmap',long:nX, long:nY, long:1, long:1, lpnull)
    hbmOld =  DllCall(hGdi32, long:'SelectObject',long:hdcMem, long:hbm)
    WHITENESS = 16711778 ; 0x00FF0062
    DllCall(hGdi32, long:'PatBlt', long:hdcMem, long:0, long:0, long:nX, long:nY, long:WHITENESS);
 
    ; Clean up.
    DllCall(hGdi32, long:'SelectObject', long:hdcMem, long:hbmOld)
    DllCall(hGdi32, long:'DeleteDC',long:hdcMem)
    DllCall(hUser32, long:'ReleaseDC',long:hwndDesktop, long:hdcDesktop)
    DllFree(hUser32)
    DllFree(hGdi32)
    return hbm
#endfunction

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Creates a structure descript string for use with DllStructAlloc.
;;
;; Returns a string description of the Wub 32 MENUITEMINFOW structure.
#DefineFunction GetMiiStructStr()
return $"
  uint::cbSize;
  uint::fMask;
  uint::fType;
  uint::fStat;
  uint::wID;
  HMENU::hSubMenu;
  HBITMAP::hbmpChecked;
  HBITMAP::hbmpUnchecked;
  DWORD_PTR::dwItemData;
  LPWSTR::dwTypeData;
  uint::cch;
  HBITMAP::hbmpItem;$"

#EndFunction

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; User defined dialog callback function
;;
;; Adds and destroys a menu item's bitmap.
#DefineFunction MenuBitmapProc(Bm_Handle,Bm_Event,Bm_Name,Bm_EventInfo,Bm_ChangeInfo)
   switch Bm_Event                                          
      case @deInit                                        
         DialogProcOptions(Bm_Handle, @dePbPush, 1)
 
         hUser32 = DllLoad('user32.dll')
         hMenuBar = DllCall(hUser32, long:'GetMenu', long:Bm_Handle)
         mii = DllStructAlloc(GetMiiStructStr())
         DllStructPoke(mii, 'cbSize', IntControl(98, mii, 1, 0, 0))
         MIIM_SUBMENU = 4
         DllStructPoke(mii, 'fMask', MIIM_SUBMENU)
         DllCall(hUser32, long:'GetMenuItemInfoW', long:hMenuBar, long:0, long:@True, lpstruct:mii)
         hmenuPopup = DllStructPeek(mii, 'hSubMenu')
         hbm = CreateMenuBitmap()
         MF_BYPOSITION = 1024  ;0x00000400L
         DllCall(hUser32, long:'SetMenuItemBitmaps',long:hmenuPopup, long:0, long:MF_BYPOSITION, long:hbm, long:hbm);
         ; aError = DllLastError()
         DllStructFree(mii)
         DllFree(hUser32)
         return(@retDefault)

      case @dePbPush

         ;  Destroy bitmaps as system won't.
         hUser32 = DllLoad('user32.dll')
         hMenuBar = DllCall(hUser32, long:'GetMenu', long:Bm_Handle)
         mii = DllStructAlloc(GetMiiStructStr())
         DllStructPoke(mii, 'cbSize', IntControl(98, mii, 1, 0, 0))
         MIIM_SUBMENU = 4
         DllStructPoke(mii, 'fMask', MIIM_SUBMENU)
         DllCall(hUser32, long:'GetMenuItemInfoW', long:hMenuBar, long:0, long:@True, lpstruct:mii)
         hmenuPopup = DllStructPeek(mii, 'hSubMenu')
         MIIM_CHECKMARKS = 8
         DllStructPoke(mii, 'fMask', MIIM_CHECKMARKS)
         DllCall(hUser32, long:'GetMenuItemInfoW', long:hmenuPopup, long:0, long:@True, lpstruct:mii)
         hGdi32 = DllLoad('Gdi32.dll')
         DllCall(hGdi32,long:'DeleteObject', long:DllStructPeek(mii, 'hbmpChecked'))
         DllCall(hGdi32,long:'DeleteObject', long:DllStructPeek(mii, 'hbmpUnchecked'))
         DllStructFree(mii)
         DllFree(hUser32)
         DllFree(hGdi32)
        break
;      case @deMiSelect                                    
;      case @deMiInit                                      
;      case @deClose                                      

   endswitch                                              
   return(@retDefault)
#EndFunction                                                

return

td:
The above example only scratches the surface.  You can also create bitmap menu items where you would need to draw the menu's text on the bitmap.

Navigation

[0] Message Index

[#] Next page

Go to full version