Windows API   メニュー

ホーム   C/C++チュートリアル


Cプログラミンの一環として始めた Windos API ですが、やってみたら面白かったので、もっと詳しく、かつ簡単に、ステップバイステップで学習するコーナーも作りました。
Windows API Primer
Primer は、入門書という意味です。

メニュー

メニューはデスクトップアプリケーションにとって重要な機能です。

簡単なメニュー

simplemenu.c


#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);
}
    


実行結果


「New」と「Open」を選んだ場合はビープ音が鳴ります。「Quit」を選んだ場合はアプリケーションが終了します。


ポップアップメニュー

ポップアップメニューは、画面を右クリックすると現れるメニューです。コンテキストメニューとも呼ばれます。

popupmenu.c


#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);
}
    


実行結果


ウィンドウを右クリックするとポップアップメニューが現れます。「New」と「Open」を選んだ場合はビープ音が鳴ります。「Quit」を選んだ場合はアプリケーションが終了します。


チェックメニュー

checkmenu.c


#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);
}
    


実行結果


「Statusbar」メニューアイテムにチェックが入っていれば、ステータスバーが表示されます。「Statubar」メニューアイテムにチェックが入っていなければ、ステータスバーは表示されません。



34700 visits
Posted: Mar. 15, 2020
Update: Mar. 16, 2020

ホーム   C/C++チュートリアル   目次