EternalWindows
ステータスバー / アイコンとツールチップ

今回のプログラムは、ステータスバーのパートにアイコンとツールチップを設定します。

#include <windows.h>
#include <commctrl.h>

#pragma comment (lib, "comctl32.lib")

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hinstPrev, LPSTR lpszCmdLine, int nCmdShow)
{
	TCHAR      szAppName[] = TEXT("sample");
	HWND       hwnd;
	MSG        msg;
	WNDCLASSEX wc;

	wc.cbSize        = sizeof(WNDCLASSEX);
	wc.style         = 0;
	wc.lpfnWndProc   = WindowProc;
	wc.cbClsExtra    = 0;
	wc.cbWndExtra    = 0;
	wc.hInstance     = hinst;
	wc.hIcon         = (HICON)LoadImage(NULL, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_SHARED);
	wc.hCursor       = (HCURSOR)LoadImage(NULL, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_SHARED);
	wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	wc.lpszMenuName  = NULL;
	wc.lpszClassName = szAppName;
	wc.hIconSm       = (HICON)LoadImage(NULL, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_SHARED);
	
	if (RegisterClassEx(&wc) == 0)
		return 0;

	hwnd = CreateWindowEx(0, szAppName, szAppName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hinst, NULL);
	if (hwnd == NULL)
		return 0;

	ShowWindow(hwnd, nCmdShow);
	UpdateWindow(hwnd);
	
	while (GetMessage(&msg, NULL, 0, 0) > 0) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return (int)msg.wParam;
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	static HWND hwndStatus = NULL;
	
	switch (uMsg) {
		
	case WM_CREATE: {
		int                  nWidth[] = {34, -1};
		HICON                hicon;
		INITCOMMONCONTROLSEX ic;
		
		ic.dwSize = sizeof(INITCOMMONCONTROLSEX);
		ic.dwICC  = ICC_BAR_CLASSES;
		InitCommonControlsEx(&ic);
		
		hwndStatus = CreateWindowEx(0, STATUSCLASSNAME, TEXT(""), WS_CHILD | WS_VISIBLE | SBT_TOOLTIPS, 0, 0, 0, 0, hwnd, (HMENU)1, ((LPCREATESTRUCT)lParam)->hInstance, NULL);
		
		SendMessage(hwndStatus, SB_SETPARTS, (WPARAM)2, (LPARAM)nWidth);

		hicon = (HICON)LoadImage(NULL, IDI_QUESTION, IMAGE_ICON, 0, 0, LR_SHARED);
		SendMessage(hwndStatus, SB_SETICON, (WPARAM)0, (LPARAM)hicon);
		SendMessage(hwndStatus, SB_SETTEXT, (WPARAM)0, (LPARAM)TEXT("ヘルプ"));
		SendMessage(hwndStatus, SB_SETTIPTEXT, (WPARAM)0, (LPARAM)TEXT("ヘルプ"));

		hicon = (HICON)LoadImage(NULL, IDI_EXCLAMATION, IMAGE_ICON, 0, 0, LR_SHARED);
		SendMessage(hwndStatus, SB_SETICON, (WPARAM)1, (LPARAM)hicon);
		SendMessage(hwndStatus, SB_SETTEXT, (WPARAM)1, (LPARAM)TEXT("警告"));

		SendMessage(hwndStatus, SB_SETMINHEIGHT, (WPARAM)34, (LPARAM)0);

		return 0;
	}

	case WM_NOTIFY: {
		if (((LPNMHDR)lParam)->code == NM_DBLCLK) {
			TCHAR szBuf[256];

			SendMessage(hwndStatus, SB_GETTEXT, (WPARAM)((LPNMMOUSE)lParam)->dwItemSpec, (LPARAM)szBuf);
			MessageBox(NULL, szBuf, TEXT("OK"), MB_OK);
		}
		return 0;
	}

	case WM_SIZE:
		SendMessage(hwndStatus, WM_SIZE, wParam, lParam);
		return 0;

	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;

	default:
		break;

	}

	return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

アイコンの設定は、SB_SETICONで行うことができます。 WPARAMはパートのインデックスを指定し、LPARAMにアイコンのハンドルを指定します。 一方、ツールチップの設定は、SB_SETTIPTEXTで行うことができます。 WPARAMはパートのインデックスを指定し、ツールチップとして表示したいテキストを指定します。 ツールチップを表示する場合は、ウインドウスタイルにSBT_TOOLTIPSを指定します。

SB_SETTIPTEXTでツールチップを指定しても、必ずツールチップが表示されるわけではないことに注意してください。 テキストが途切れることなく完全に表示されているパートではツールチップが表示されないため、 幅が無制限である2番目のパートではSB_SETTIPTEXTを実行しても意味はありません。 一方、幅に制限のある1番目のパートではアイコンしか表示されませんから、 SB_SETTIPTEXTでツールチップを設定する意味はあります。 なお、SB_SETMINHEIGHTでステータスバーの最小の高さを設定しているのは、 LoadImageで取得できる既定のアイコンの高さが大きいためです。

ステータスバーのパートでダブルクリックを行った場合は、 通知コードがNM_DBLCLKであるWM_NOTIFYが送られます。 今回は、ダブルクリックされたパートのテキストを表示しています。

case WM_NOTIFY: {
	if (((LPNMHDR)lParam)->code == NM_DBLCLK) {
		TCHAR szBuf[256];

		SendMessage(hwndStatus, SB_GETTEXT, (WPARAM)((LPNMMOUSE)lParam)->dwItemSpec, (LPARAM)szBuf);
		MessageBox(NULL, szBuf, TEXT("OK"), MB_OK);
	}
	return 0;
}

NM_DBLCLKの際のlParamには、NMMOUSE構造体のアドレスが格納されています。 この構造体のdwItemSpecにはパートのインデックスが格納されているため、 これをSB_GETTEXTに指定することによって、パートのテキストを取得することができます。


戻る