Не знаю, как правильно будет назвать данную тему. Суть в том, что можно создавать меню «на лету». Этому посвящена вторая часть статьи про создание меню для приложения. В прошлый раз мы всё делали через файлы ресурсов.
Поскольку мы не будем использовать файлы ресурсов, в начало файла menu_two.cpp добавим идентификаторы сразу после директивы #include:
#define ID_FILE_EXIT 9001
#define ID_STUFF_GO 9002
Если мы добавим в файл такую строку:
hIcon = LoadImage(NULL, L"menu_two.ico", IMAGE_ICON, 32, 32, LR_LOADFROMFILE);
То получим сообщение об ошибке:
В этом случае нам нужно просто явно указать тип, с котором мы работаем:
hIcon = (HICON) LoadImage(NULL, L"menu_two.ico", IMAGE_ICON, 32, 32, LR_LOADFROMFILE);
В случае динамического меню нам уже не потребуются эти строчки, поэтому их можно удалить:
wc.lpszMenuName = MAKEINTRESOURCE(IDR_MYMENU);
wc.hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MYICON));
wc.hIconSm = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MYICON), IMAGE_ICON, 16, 16, 0);
Если удалить старую папку .VSCode, в которой была задача сборки проекта с файлом ресурсов, мы сможем пересобрать наш проект без учёта файла ресурсов. Правда в этот раз меня ждало другое сообщение об ошибке. Оно появилось когда я попытался запустить скомпилированный файл:
Что ж, эту ошибку оказалось не так просто устранить, т.к. здесь нам не было указано, в чём именно проблема. Для начала зададим явный размер структуры WNDCLASSEX:
WNDCLASSEX wc = {0};
Уже лучше — мы получили новое сообщение об ошибке, на этот раз что-то конкретное:
Следом за ней ещё одно:
Правда на этот раз программа всё же запустится и можно будет открывать меню.
И эти ошибки исправить довольно просто — нам нужно, чтобы файл «menu_two.ico» находился в той же папке, что и запускной файл.
Таким образом полный текст файла menu_two.cpp будет таким:
#define UNICODE
#pragma comment(lib, "user32.lib")
#include <windows.h>
#define ID_FILE_EXIT 9001
#define ID_STUFF_GO 9002
const wchar_t g_szClassName[] = L"myWindowClass";
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CREATE:
{
HMENU hMenu, hSubMenu;
HICON hIcon, hIconSm;
hMenu = CreateMenu();
hSubMenu = CreatePopupMenu();
AppendMenu(hSubMenu, MF_STRING, ID_FILE_EXIT, L"E&xit");
AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, L"&File");
hSubMenu = CreatePopupMenu();
AppendMenu(hSubMenu, MF_STRING, ID_STUFF_GO, L"&Go");
AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, L"&Stuff");
SetMenu(hwnd, hMenu);
hIcon = (HICON)LoadImage(NULL, L"menu_two.ico", IMAGE_ICON, 32, 32, LR_LOADFROMFILE);
if (hIcon)
SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
else
MessageBox(hwnd, L"Could not load large icon!", L"Error", MB_OK | MB_ICONERROR);
hIconSm = (HICON)LoadImage(NULL, L"menu_two.ico", IMAGE_ICON, 16, 16, LR_LOADFROMFILE);
if (hIconSm)
SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)hIconSm);
else
MessageBox(hwnd, L"Could not load small icon!", L"Error", MB_OK | MB_ICONERROR);
}
break;
case WM_LBUTTONDOWN:
{
wchar_t szFileName[MAX_PATH];
HINSTANCE hInstance = GetModuleHandle(NULL);
GetModuleFileName(hInstance, szFileName, MAX_PATH);
MessageBox(hwnd, szFileName, L"This program is:", MB_OK | MB_ICONINFORMATION);
}
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case ID_FILE_EXIT:
PostMessage(hwnd, WM_CLOSE, 0, 0);
break;
case ID_STUFF_GO:
break;
}
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc = {0};
HWND hwnd;
MSG Msg;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClassName;
if (!RegisterClassEx(&wc))
{
MessageBox(NULL, L"Window Registration Failed!", L"Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
L"The title of my window",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,
NULL, NULL, hInstance, NULL);
if (hwnd == NULL)
{
MessageBox(NULL, L"Window Creation Failed!", L"Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while (GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
- EVE-Online: Фильтры каналов - 23.11.2024
- Не приходит СМС для авторизации на сайте Госуслуги - 01.11.2024
- VSCode: Найти и удалить элементы xml - 29.10.2024