Announcement

Collapse
No announcement yet.

Checkbox inside menu?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • norbert doerre
    replied
    This is an old one, but it works!

    Code:
    '-------------------------------------------------------------------------------------------------------
    ' INCLUDE FILES
    '-------------------------------------------------------------------------------------------------------
    #If Not %Def(%WINAPI)
        #INCLUDE "WIN32API.INC"
    #ENDIF
    
    '-------------------------------------------------------------------------------------------------------
    ' FUNCTION DECLARATIONS
    '-------------------------------------------------------------------------------------------------------
    Declare Sub SwitchMenuItemCheck(sMenuString As String)
    Declare Sub SetMenuItemCheck(sMenuString As String, lCheckState As long)
    Declare Function GetMenuItemCheck(sMenuString As String) As long
    Declare Function VCIsCurrentWorldValid Lib "VCMAIN32.DLL" Alias "VCIsCurrentWorldValid" () As Integer
    Declare Function VCGethWndFrame Lib "VCMAIN32.DLL" Alias "VCGethWndFrame" () As Long
    Declare Sub SetMenuChecksByDrawingSettings()
    
    '-------------------------------------------------------------------------------------------------------
    '  SUB GetMenuItemCheck
    '-------------------------------------------------------------------------------------------------------
    Function GetMenuItemCheck(sMenuString As String) As Long
    	Local hWnd As Long
    	Local hMenu As Long
    	Local lMenuCount As Long
    	Local lSubMenuCount As Long
    	Local hSubMenu As Long
    	Local ItemID As Long
    	Local lRes As Long
    	Local szMenuString As Asciiz * 64
    	Local MainMenuIndex As Long
    	Local SubMenuIndex As Long
    	Local iState As Integer
    	Function = %MF_UNCHECKED
    	If VCIsCurrentWorldValid() = 0 Then Exit Function
    	hWnd = VCGetHwndFrame() 'Mcadd frame handle
    '	hMenu = GetSystemMenu(hWnd, 0) 'prüfen, ob Systemmenü aktiv
    '	lSysMenuCount = GetMenuItemCount(hMenu) 'Anzahl der aktiven Systemmenü-Items
    	hMenu = GetMenu(hWnd)	'Handle des Mcadd Hauptmenüs
    	lMenuCount = GetMenuItemCount(hMenu) 'Anzahl der Untermenüs im Hauptmenü = 14 ohne Systemmenü, 18 mit Systemmenü
    	For MainMenuIndex = 0 To lMenuCount -1
    		hSubMenu = GetSubMenu(hMenu, MainMenuindex) 'Handle des Untermenüs mit Menütitel "Layer"
    		lSubMenuCount = GetMenuItemCount(hSubMenu)
    		For SubMenuIndex = 0 To lSubMenuCount - 1
    			ItemID = GetMenuItemID(hSubMenu, SubMenuIndex)	'ID des ersten Menüeintrags im Untermenü 4
    			lRes = GetMenuString(hSubMenu, ItemID, szMenuString, 0, %MF_BYCOMMAND) 'zuerst mit Parameter 0 nur die Länge ermitteln
    			lRes = GetMenuString(hSubMenu, ItemID, szMenuString, lRes, %MF_BYCOMMAND) 'jetzt über die Länge den String ermitteln
    			If InStr(szMenuString, sMenuString) Then
    				iState = GetMenuState(hMenu, ItemID, %MF_BYCOMMAND Or %MF_CHECKED)
    				Function = iState
    				Exit For
    			End If
    		Next SubMenuIndex
    	Next MainMenuIndex
    End Function
    
    '-------------------------------------------------------------------------------------------------------
    '  SUB SetMenuItemCheck
    '-------------------------------------------------------------------------------------------------------
    Sub SetMenuItemCheck(sMenuString As String, iCheckVal As Long)
    	'INPUT: iCheckVal = %MF_CHECKED oder iCheckVal = %MF_UNCHECKED
    	'INPUT alternativ: iCheckVal = 1 oder iCheckVal = 0
    	Local hWnd As Long
    	Local hMenu As Long
    	Local lMenuCount As Long
    	Local lSubMenuCount As Long
    	Local hSubMenu As Long
    	Local ItemID As Long
    	Local lRes As Long
    	Local MainMenuIndex As Long
    	Local SubMenuIndex As Long 
    	Local szMenuString As Asciiz * 64
    	If VCIsCurrentWorldValid() = 0 Then Exit Sub
    	If iCheckVal = 0 Then 
    		iCheckVal = %MF_UNCHECKED
    	ElseIf iCheckVal = 1 Then
    		iCheckVal = %MF_CHECKED
    	End If
    	hWnd = VCGetHwndFrame() 'Mcadd frame handle
    '	hMenu = GetSystemMenu(hWnd, 0) 'prüfen, ob Systemmenü aktiv
    '	lSysMenuCount = GetMenuItemCount(hMenu) 'Anzahl der aktiven Systemmenü-Items
    	hMenu = GetMenu(hWnd)	'Handle des Mcadd Hauptmenüs
    	lMenuCount = GetMenuItemCount(hMenu) 'Anzahl der Untermenüs im Hauptmenü = 14 ohne Systemmenü, 18 mit Systemmenü
    	For MainMenuIndex = 0 To lMenuCount -1
    		hSubMenu = GetSubMenu(hMenu, MainMenuindex) 'Handle des Untermenüs per MainMenuindex
    		lSubMenuCount = GetMenuItemCount(hSubMenu)
    		For SubMenuIndex = 0 To lSubMenuCount - 1
    			ItemID = GetMenuItemID(hSubMenu, SubMenuIndex)	'ID des ersten Menüeintrags im Untermenü per SubMenuIndex
    			lRes = GetMenuString(hSubMenu, ItemID, szMenuString, 0, %MF_BYCOMMAND) 'zuerst mit Parameter 0 nur die Länge ermitteln
    			lRes = GetMenuString(hSubMenu, ItemID, szMenuString, lRes, %MF_BYCOMMAND) 'jetzt über die Länge den String ermitteln
    			If InStr(szMenuString, sMenuString) Then
    				lRes = CheckMenuItem(hSubMenu, ItemID, %MF_BYCOMMAND Or iCheckVal)
    				Exit For
    			End If
    		Next SubMenuIndex
    	Next MainMenuIndex
    End Sub

    Leave a comment:


  • Michael Mattias
    replied
    DrawFrameControl() is used at drawing time, not at menu creation time.

    If the menu is MF_OWNERDRAW style, that would be on the WM_DRAWITEM notification, and you have to process the WM_MEASUREITEM notification, too.

    Leave a comment:


  • Egbert Zijlema
    replied
    This code does not create the bitmaps

    Well, I've made this pseudo code, but I don't see the checkbox appear.
    I think something is wrong in respect with the memory device context stuff. Normally hDC = CreateCompatibleDC(0) should be followed by SelectObject hDC, hObject, but which handle of which object must we select, since the bitmap handles will be set later by DrawFrameControl API function?

    Code:
    #COMPILE EXE
    #DIM ALL
    
    #INCLUDE "WIN32API.INC"
    
    %IDM_OPT1 = 1002
    
    FUNCTION AttachMenu(BYVAL hDlg AS DWORD) AS DWORD
      LOCAL cxMnu AS LONG, cyMnu AS LONG
      LOCAL hDC AS DWORD, hBmp1 AS DWORD, hBmp2 AS DWORD, rt AS RECT
      LOCAL hMenu  AS DWORD
      LOCAL hPopUp AS DWORD
    
      MENU NEW BAR TO hMenu
      MENU NEW POPUP TO hPopUp
      MENU ADD POPUP, hMenu, "&Edit", hPopUp, %MF_ENABLED
      MENU ADD STRING, hPopUp, "Option1", %IDM_OPT1, %MF_ENABLED
      MENU ATTACH hMenu, hDlg
    
      hDC = CreateCompatibleDC(0)
      cxMnu = GetSystemMetrics(%SM_CXMENUCHECK)
      cyMnu = GetSystemMetrics(%SM_CYMENUCHECK)
    
      rt.nLeft = 0
      rt.nTop = 0
      rt.nRight = cxMnu - 1
      rt.nBottom = cyMnu - 1
    
      hBmp1 = DrawFrameControl(hDC, rt, %DFC_BUTTON, %DFCS_BUTTONCHECK OR %DFCS_CHECKED)
      hBmp2 = DrawFrameControl(hDC, rt, %DFC_BUTTON, %DFCS_BUTTONCHECK)
    
      SetMenuItemBitmaps hMenu, %IDM_OPT1, %MF_BYCOMMAND, hBmp2, hBmp1
      FUNCTION = hMenu
    END FUNCTION
    
    CALLBACK FUNCTION ShowDlgProc()
      SELECT CASE AS LONG CBMSG
        CASE %WM_COMMAND
          SELECT CASE AS LONG CBCTL
            CASE %IDM_OPT1
              MSGBOX "%IDM_OPT1 = " & FORMAT$(%IDM_OPT1), 64 OR %MB_TASKMODAL, " Bmp demo.."
          END SELECT
      END SELECT
    END FUNCTION
    
    FUNCTION PBMAIN()
      LOCAL hDlg AS DWORD, dwRet AS DWORD
      DIALOG NEW %HWND_DESKTOP, " Menu bitmap demo..", 70, 70, 201, 133, %WS_CAPTION OR %WS_MINIMIZEBOX OR %WS_SYSMENU TO hDlg
      dwRet = AttachMenu(hDlg)
      DIALOG SHOW MODAL hDlg, CALL ShowDlgProc
    END FUNCTION

    Leave a comment:


  • Edwin Knoppert
    replied
    Afaik a menu does not support checkboxes behaviour.
    The radio it does and is a bullet.
    You can 'uncheck' when the item is clicked and therefore make it work as a checkbox.

    Other option is already suggested, ownerdrawn.

    Leave a comment:


  • Egbert Zijlema
    replied
    MENUITEMINFO is not the solution

    When using SetMenuItemInfo (API) a coder can change the standard checkmark of a menu item into a bullet. Although defined as MFT_RADIOCHECK, it is not really a radio-button but a normal bullet, which is only displayed when the state of the menu-item is MF_CHECKED (MFS_CHECKED). It disappears when the state of the item becomes unchecked. In fact, same behaviour as standard checkmark. In other words: lots of fuss to create no change.

    What I want to achieve is a real checkbox that can be checked/unchecked by the user. So I'm going to try Michael's suggestion now: a second dialog that pops up instead of the menu. This means that the original menu should be disabled (it never opens) but should nevertheless receive a notification message in order to launch the replacing dialog. How?

    Thanks, guys, for all your help, so far.

    Leave a comment:


  • Chris Boss
    replied
    The SetMenuItemBitmaps API function allows you to replace the standard checkmark images with your own custom bitmaps. You can do this by either drawing your own Bitmaps and use them, or by creating a blank bitmap in memory and drawing the checkbox images using the DrawFrameControl API function to draw your images.

    DrawFrameControl is a very useful function, since it can draw any of the common window elements used by most controls.

    The GetSystemMetrics API function is useful to determine the actual size a number of window elements should be. The SM_CXMENUCHECK and SM_CYMENUCHECK flags should be used to find the proper size for a check image for menus. Then use DrawFrameControl to draw it the correct size in a blank bitmap and then use that bitmap in SetMenuItemBitmap.

    Leave a comment:


  • Michael Mattias
    replied
    Or, you could make a dialog/window with which just looks like a menu and show it when the user would expect it.

    Seems to me someone did an owner-drawn menu demo here just in the last couple of weeks, except it was NOT in the Source Code forum. Try a full text search on "%MF_OWNERDRAW" since that would have had to appear in the code. WM_MEASUREITEM would also have had to appear.

    Leave a comment:


  • Chris Holbrook
    replied
    Check out MENUITEMINFO in the Win32 API help

    Leave a comment:


  • Egbert Zijlema
    started a topic Checkbox inside menu?

    Checkbox inside menu?

    I don't like visible checkboxes in a well-designed GUI (transparent dialog with photograph as a background, for instance). They spoil the effect. Instead, I can use a menu with options that have either the %MF_CHECKED or the %MF_UNCHECKED state. It works, but for the user it may not be very clear what happens, because the checkmarks disappear/reappear "under water", so to speak.

    Now I want to try to create a menu with checkboxes inside, replacing the normal checked/unchecked options. I guess that I should create an owner drawn menu. Unfort., I have not the slightest idea, where to start. Are there samples around here? A search for "checkbox menu" did not deliver anything usable, nor did a search for "owner drawn menu".

    Thanks for any hint, help or code sample.
Working...
X