ビットマップからリージョンを作るってのはよくありますけど、ただの文字列のリージョンを作りたいときに、わざわざビットマップを作るのはめんどうですよね。(そもそもそんなことする人いないか?)
なので文字列のリージョンを作るものを作ってみました。
#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などにかえてみたりして、最適化してみてください。