ビットマップからリージョンを作るってのはよくありますけど、ただの文字列のリージョンを作りたいときに、わざわざビットマップを作るのはめんどうですよね。(そもそもそんなことする人いないか?)
なので文字列のリージョンを作るものを作ってみました。
#include <windows.h> #include <stdio.h> #define PROGRAM_NAME "RgnTest" int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmd, int nCmdShow); HWND InitWindow (void); LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); HINSTANCE g_hInstance; //////////////////////////////////////////////////////////////////////////////////////////////// int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmd, int nCmdShow) { MSG msg; BOOL bRet; g_hInstance = hInstance; InitWindow(); while ( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0 ) { if (bRet == -1) { MessageBox(0, "handle the error and possibly exit", "error", MB_ICONSTOP); break; } else { TranslateMessage (&msg); DispatchMessage (&msg); } } return msg.wParam; } HWND InitWindow (void) { HWND hWnd; WNDCLASSEX wcex; ZeroMemory((LPVOID)&wcex, sizeof(WNDCLASSEX)); wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = 0; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = g_hInstance; wcex.hIcon = NULL; wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = CreateSolidBrush(RGB(0,0,0)); wcex.lpszMenuName = NULL; wcex.lpszClassName = PROGRAM_NAME; wcex.hIconSm = NULL; RegisterClassEx(&wcex); //ウィンドウ作成 hWnd=CreateWindowEx( 0, PROGRAM_NAME, PROGRAM_NAME, WS_POPUP, 200, //位置とか大きさとかはもちろん適当 200, 700, 50, NULL, NULL, g_hInstance, NULL ); ShowWindow(hWnd, SW_SHOW); UpdateWindow(hWnd); return hWnd; } LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; char *text = "それっぽいリージョン"; //表示する文字 //リージョン用 COLORREF tcolor = RGB(0,0,0); //透過色(なぜか背景色を黒にしていたので黒) static HRGN hRgn; HRGN hRgnTemp; int width, height, x, y; switch (message) { case WM_CREATE: return 0; case WM_COMMAND: return 0; case WM_LBUTTONDOWN: ReleaseCapture(); SendMessage(hwnd, WM_NCLBUTTONDOWN, HTCAPTION, 0); return 0; //普通はこんなことやるのだろうか… case WM_RBUTTONDOWN: hdc = GetDC(hwnd); RECT r; GetWindowRect(hwnd, &r); width = r.right - r.left; height = r.bottom - r.top; hRgn = CreateRectRgn(0,0,0,0); hRgnTemp = CreateRectRgn(0,0,0,0); for (y = 0;y < height;y++) { for (x = 0;x < width;x++) { if (GetPixel(hdc, x, y) != tcolor) { HRGN hRgnPixel; hRgnPixel = CreateRectRgn(x,y,x+1,y+1); hRgnTemp = hRgn; CombineRgn(hRgn, hRgnTemp, hRgnPixel, RGN_OR); DeleteObject(hRgnPixel); } } } SetWindowRgn(hwnd, hRgn, TRUE); DeleteObject(hRgnTemp); ReleaseDC(hwnd, hdc); return 0; case WM_PAINT: hdc = BeginPaint(hwnd, &ps); HFONT hFont, hOldFont; hFont = CreateFont( 30, 30, 0, 0, FW_HEAVY, FALSE, FALSE, FALSE, SHIFTJIS_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, FIXED_PITCH | FF_MODERN, "MS ゴシック" ); hOldFont = (HFONT)SelectObject(hdc, hFont); //もちろん色も表示位置も適当 SetBkMode(hdc, TRANSPARENT); SetTextColor(hdc, RGB(255, 0, 0)); TextOut(hdc, 1, 1, text, strlen(text)); SelectObject(hdc, hOldFont); DeleteObject(hFont); EndPaint(hwnd, &ps); return 0; case WM_CLOSE: DestroyWindow(hwnd); return 0; case WM_DESTROY: if (hRgn != NULL) DeleteObject(hRgn); PostQuitMessage(0); break; default: return (DefWindowProc(hwnd,message,wParam,lParam)); } return 0L; }
自Windowのデバイスコンテキストに書かれてるものを、GetPixelで一ピクセルごとに色を見ていって、CombineRgnで合成しまくってるだけです。
処理が結構重いです。やる気がある人はCreateRectRgnのところをExtCreateRegionなどにかえてみたりして、最適化してみてください。