Cプログラミンの一環として始めた Windos API ですが、やってみたら面白かったので、もっと詳しく、かつ簡単に、ステップバイステップで学習するコーナーも作りました。
Windows API Primer
Primer は、入門書という意味です。
メニューはデスクトップアプリケーションにとって重要な機能です。
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void AddMenus(HWND);
#define NEW 1
#define OPEN 2
#define QUIT 3
int WINAPI WinMain (HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
WNDCLASS wc;
HWND hwnd;
MSG msg;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpszMenuName = NULL;
wc.lpszClassName = TEXT("SimpleMenu");
RegisterClass (&wc);
hwnd = CreateWindow (TEXT("SimpleMenu"),
TEXT("SimpleMenu"),
WS_OVERLAPPEDWINDOW,
(GetSystemMetrics(SM_CXSCREEN) - 400) / 2,
(GetSystemMetrics(SM_CYSCREEN) - 250) / 2,
400,
250,
NULL,
NULL,
hInstance,
NULL);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage (&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CREATE:
AddMenus(hwnd);
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case NEW:
case OPEN:
MessageBeep(MB_ICONINFORMATION);
break;
case QUIT:
SendMessage(hwnd, WM_CLOSE, 0, 0);
break;
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
void AddMenus(HWND hwnd)
{
HMENU hMenubar;
HMENU hMenu;
hMenubar = CreateMenu();
hMenu = CreateMenu();
AppendMenu(hMenu, MF_STRING, NEW, TEXT("&New"));
AppendMenu(hMenu, MF_STRING, OPEN, TEXT("&Open"));
AppendMenu(hMenu, MF_SEPARATOR, 0, NULL);
AppendMenu(hMenu, MF_STRING, QUIT, TEXT("&Quit"));
AppendMenu(hMenubar, MF_POPUP, (UINT_PTR)hMenu, TEXT("&File"));
SetMenu(hwnd, hMenubar);
}
ポップアップメニューは、画面を右クリックすると現れるメニューです。コンテキストメニューとも呼ばれます。
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
#define NEW 1
#define OPEN 2
#define QUIT 3
int WINAPI WinMain (HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
WNDCLASS wc;
HWND hwnd;
MSG msg;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpszMenuName = NULL;
wc.lpszClassName = TEXT("PopupMenu");
RegisterClass (&wc);
hwnd = CreateWindow (TEXT("PopupMenu"),
TEXT("PopupMenu"),
WS_OVERLAPPEDWINDOW,
(GetSystemMetrics(SM_CXSCREEN) - 400) / 2,
(GetSystemMetrics(SM_CYSCREEN) - 250) / 2,
400,
250,
NULL,
NULL,
hInstance,
NULL);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage (&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
HMENU hMenu;
POINT point;
switch (msg)
{
case WM_COMMAND:
switch(LOWORD(wParam))
{
case NEW:
case OPEN:
MessageBeep(MB_ICONINFORMATION);
break;
case QUIT:
SendMessage(hwnd, WM_CLOSE, 0, 0);
break;
}
break;
case WM_RBUTTONUP:
point.x = LOWORD(lParam);
point.y = HIWORD(lParam);
hMenu = CreatePopupMenu();
ClientToScreen(hwnd, &point);
AppendMenu(hMenu, MF_STRING, NEW, TEXT("&New" ));
AppendMenu(hMenu, MF_STRING, OPEN, TEXT("&Open"));
AppendMenu(hMenu, MF_SEPARATOR, 0, NULL );
AppendMenu(hMenu, MF_STRING, QUIT, TEXT("&Quit"));
TrackPopupMenu(hMenu, TPM_RIGHTBUTTON, point.x, point.y, 0, hwnd, NULL);
DestroyMenu(hMenu);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
#include <windows.h>
#include <commctrl.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void AddMenus(HWND);
#define VIEW_STB 1
HWND gStb;
HMENU gMenu;
int WINAPI WinMain (HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
WNDCLASS wc;
HWND hwnd;
MSG msg;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpszMenuName = NULL;
wc.lpszClassName = TEXT("CheckMenu");
RegisterClass (&wc);
hwnd = CreateWindow (TEXT("CheckMenu"),
TEXT("CheckMenu"),
WS_OVERLAPPEDWINDOW,
(GetSystemMetrics(SM_CXSCREEN) - 400) / 2,
(GetSystemMetrics(SM_CYSCREEN) - 250) / 2,
400,
250,
NULL,
NULL,
hInstance,
NULL);
ShowWindow(hwnd, nCmdShow);
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage (&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
UINT state;
switch(msg)
{
case WM_CREATE:
AddMenus(hwnd);
gStb = CreateWindowExW(0, STATUSCLASSNAMEW, NULL,
WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hwnd,
(HMENU) 1, GetModuleHandle(NULL), NULL);
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case VIEW_STB:
state = GetMenuState(gMenu, VIEW_STB, MF_BYCOMMAND);
if (state == MF_CHECKED)
{
ShowWindow(gStb, SW_HIDE);
CheckMenuItem(gMenu, VIEW_STB, MF_UNCHECKED);
} else {
ShowWindow(gStb, SW_SHOWNA);
CheckMenuItem(gMenu, VIEW_STB, MF_CHECKED);
}
break;
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
void AddMenus(HWND hwnd)
{
HMENU hMenubar;
hMenubar = CreateMenu();
gMenu = CreateMenu();
AppendMenu(gMenu, MF_STRING, VIEW_STB, TEXT("&Statusbar"));
CheckMenuItem(gMenu, VIEW_STB, MF_CHECKED);
AppendMenu(hMenubar, MF_POPUP, (UINT_PTR)gMenu, TEXT("&View"));
SetMenu(hwnd, hMenubar);
}