Menu, Создание динамического меню.

Тема в разделе "WASM.WIN32", создана пользователем Andrey_59, 25 май 2023.

  1. Andrey_59

    Andrey_59 Member

    Публикаций:
    0
    Регистрация:
    20 фев 2021
    Сообщения:
    81
    Код (C++):
    1. #include<windows.h>
    2. #include<tchar.h>
    3.  
    4. BOOL RegClass(WNDPROC, LPCTSTR, UINT);
    5.  
    6. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    7. LRESULT CALLBACK DlgProc(HWND, UINT, WPARAM, LPARAM);
    8. HMENU CreateMenu(HWND hwnd);
    9.  
    10. #define CM_FILE_CREATE          2000
    11. #define CM_FILE_QUIT            2001
    12. #define CM_FILE_NEW             2002
    13. #define CM_FILE_OPEN            2003
    14. #define CM_FILE_SAVE            2004
    15.  
    16.  
    17. HINSTANCE hInstance = NULL;
    18.  
    19. const TCHAR szMainClass[] = TEXT("_MainClass_");
    20. const TCHAR szTitle[] = TEXT("Calculator");
    21.  
    22. //#pragma pack(push, 1)
    23.  
    24. typedef struct {
    25.     WORD  wVersion;
    26.     WORD  wOffset;
    27.     DWORD  dwHelpId;
    28. } MENUEX_TEMPLATE_HEADER;
    29.  
    30. typedef struct {
    31.     //DWORD  dwHelpId;
    32.     DWORD  dwType;
    33.     DWORD  dwState;
    34.     DWORD  menuId;
    35.     WORD  bResInfo;
    36.     WCHAR  szText[1];
    37.     //DWORD  dwHelpId;
    38.  
    39. } MENUEX_TEMPLATE_ITEM;
    40.  
    41. //#pragma pack(pop)
    42.  
    43.  
    44. int WINAPI _tWinMain(HINSTANCE hInst, HINSTANCE hPrevInstance,
    45.     LPTSTR szCmdLine, int nCmdShow)
    46. {
    47.     HWND hwnd = NULL;
    48.     hInstance = hInst;
    49.     MSG msg = { 0 };
    50.  
    51.     if (!RegClass(WndProc, szMainClass, COLOR_WINDOW))
    52.         return FALSE;
    53.  
    54.     hwnd = FindWindow(szMainClass, szTitle);
    55.     if (hwnd)
    56.     {
    57.         return 0;
    58.     }
    59.     if (!(hwnd = CreateWindow(szMainClass, szTitle,
    60.         WS_OVERLAPPEDWINDOW,
    61.         CW_USEDEFAULT, 0,
    62.         CW_USEDEFAULT, 0,
    63.         NULL, (HMENU)NULL,
    64.         hInstance, NULL)))
    65.     {
    66.         return FALSE;
    67.     }
    68.  
    69.     ShowWindow(hwnd, nCmdShow);
    70.     UpdateWindow(hwnd);
    71.  
    72.     while (GetMessage(&msg, NULL, 0, 0))
    73.     {
    74.         TranslateMessage(&msg);
    75.         DispatchMessage(&msg);
    76.     }
    77.     UnregisterClass(szMainClass, hInstance);
    78.     return msg.wParam;
    79. }
    80.  
    81. LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    82. {
    83.     static int cx, cy;
    84.     //static kmenu menu1;
    85.     static HMENU hMainMenu, hFileMenu;
    86.     //static char szExpression[256];
    87.     switch (msg)
    88.     {
    89.     case WM_CREATE:
    90.     {
    91.         hMainMenu = CreateMenu(hwnd);
    92.  
    93.         SetMenu(hwnd, hMainMenu);
    94.         DrawMenuBar(hwnd);
    95.  
    96.         return 0;
    97.     }
    98.     case WM_SIZE:
    99.     {
    100.         cx = LOWORD(lParam);
    101.         cy = HIWORD(lParam);
    102.  
    103.         return 0;
    104.     }
    105.     case WM_COMMAND:
    106.     {
    107.         switch(LOWORD(wParam))
    108.         {
    109.             case CM_FILE_OPEN:
    110.             {
    111.                 MessageBox(NULL, TEXT("CM_FILE_OPEN"), TEXT("MESSAGE"),
    112.                                  MB_OK);
    113.                 return 0;
    114.             }
    115.             default:
    116.                 break;
    117.         }
    118.         return 0;
    119.     }
    120.     case WM_DESTROY:
    121.     {
    122.         PostQuitMessage(0);
    123.         return 0;
    124.     }
    125.     }
    126.     return DefWindowProc(hwnd, msg, wParam, lParam);
    127. }
    128.  
    129. BOOL RegClass(WNDPROC proc, LPCTSTR szName, UINT brBackground)
    130. {
    131.     WNDCLASS wc = { 0 };
    132.     wc.style = 0;
    133.     wc.cbClsExtra = wc.cbWndExtra = 0;
    134.     wc.hInstance = hInstance;
    135.     wc.lpfnWndProc = proc;
    136.     wc.hbrBackground = (HBRUSH)(brBackground + 1);
    137.     wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    138.     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    139.     wc.lpszMenuName = (LPCTSTR)NULL;
    140.     wc.lpszClassName = szName;
    141.  
    142.     return (RegisterClass(&wc) != 0);
    143. }
    144.  
    145. HMENU CreateMenu(HWND hwnd)
    146. {
    147.     BYTE* p, * pmenuTempl;
    148.     p = pmenuTempl = (BYTE*)LocalAlloc(LPTR, 1024);
    149.     if (!p)
    150.     {
    151.         MessageBox(NULL, TEXT("Can't memory allocated"),
    152.             TEXT("Error"), MB_OK);
    153.         return (HMENU)NULL;
    154.     }
    155.  
    156.     MENUEX_TEMPLATE_HEADER* lpmth;
    157.     MENUEX_TEMPLATE_ITEM*   lpmti;
    158.  
    159.  
    160.  
    161.     lpmth = (MENUEX_TEMPLATE_HEADER*)p;
    162.     lpmth->wVersion = 1;
    163.     lpmth->wOffset  = 4;
    164.     lpmth->dwHelpId = 0;
    165.  
    166.     LPWSTR szDst;
    167.     LPCWSTR szSrc;
    168.     //ULONG_PTR ui = 0;
    169.  
    170.     int flag = 4;
    171.  
    172.     lpmti = (MENUEX_TEMPLATE_ITEM*)(lpmth+1);
    173.     lpmti->dwType   = MFT_STRING;
    174.     lpmti->dwState  = MFS_ENABLED;
    175.     lpmti->menuId   = 0x0;
    176.     lpmti->bResInfo = 0x01;
    177.     szDst = (LPWSTR)lpmti->szText;
    178.     szSrc = TEXT("FILE");
    179.     for (; *szDst++ = *szSrc++; flag ^= 2)
    180.         ;
    181.     //if(lpmti->bResInfo & 1)
    182.     *((DWORD*)szDst) = 0;
    183.  
    184.     lpmti = (MENUEX_TEMPLATE_ITEM*)(((BYTE*)szDst) + flag);
    185.  
    186.     flag = 0;
    187.     lpmti->dwType = MFT_STRING;
    188.     lpmti->dwState = MFS_ENABLED;
    189.     lpmti->menuId = CM_FILE_NEW;
    190.     lpmti->bResInfo = 0x0;
    191.     szDst = (LPWSTR)lpmti->szText;
    192.     szSrc = (LPCWSTR)TEXT("New");
    193.     for(; *szDst++ = *szSrc++; flag ^= 2)
    194.         ;
    195.  
    196.     lpmti = (MENUEX_TEMPLATE_ITEM*)(((BYTE*)szDst) + flag);
    197.  
    198.     //4
    199.     flag = 0;
    200.  
    201.     lpmti->dwType = MFT_STRING;
    202.     lpmti->dwState = MFS_ENABLED;
    203.     lpmti->menuId = CM_FILE_QUIT;
    204.     lpmti->bResInfo = 0x80;
    205.     szDst = (LPWSTR)lpmti->szText;
    206.     szSrc = TEXT("Exit");
    207.     for (; *szDst++ = *szSrc++; flag ^= 2)
    208.         ;
    209.  
    210.     lpmti = (MENUEX_TEMPLATE_ITEM*)(((BYTE*)szDst) + flag);
    211.  
    212.     p = (BYTE*)(lpmti);
    213.     int size = (p - pmenuTempl);
    214.  
    215.     HMENU hMenuA = ::LoadMenuIndirectW(/*(const MENUTEMPLATE*)*/lpmth);
    216.     HMENU hMenu = ::LoadMenuIndirectW((const MENUTEMPLATE*)lpmth);
    217.     if (!hMenu)
    218.     {
    219.         DWORD er = GetLastError();
    220.         DWORD dwEr = er;
    221.     }
    222.  
    223.     LocalFree(LocalHandle(pmenuTempl));
    224.  
    225.     return hMenu;
    226. }
     

    Вложения:

    Последнее редактирование: 6 июн 2023
  2. MaKsIm

    MaKsIm Member

    Публикаций:
    0
    Регистрация:
    11 фев 2008
    Сообщения:
    94
    В данном случае надо у FILE указать флаги 129 (0x81) т.к. он последний пункт в своей ветке и у него есть подпункты меню.

    В моем примере такое было. Смотри на меню '?' в моем примере.

     
    Andrey_59 нравится это.
  3. Andrey_59

    Andrey_59 Member

    Публикаций:
    0
    Регистрация:
    20 фев 2021
    Сообщения:
    81
    А это что вообще за значение, откуда я его знать должен, если в описании
    MENUEX_TEMPLATE_ITEM присутствуют только значения 0x80, 0x01, про 0x81 ничего нигде не говорится.
     
  4. MaKsIm

    MaKsIm Member

    Публикаций:
    0
    Регистрация:
    11 фев 2008
    Сообщения:
    94
    Т.е. про битовые флаги вы не слышали...
     
    Andrey_59 нравится это.
  5. Andrey_59

    Andrey_59 Member

    Публикаций:
    0
    Регистрация:
    20 фев 2021
    Сообщения:
    81
    Да куда уж нам уж. С такими описаниями и без побитовых операций ничего не ясно.