『パスの使用』
ここでは、 特定のポイント サイズのフォントを
([フォントの指定]ダイアログ ボックスを使って) ユーザーが選択し、
(そのフォントで描画したテキストから) クリップ パスを作成し、 テキストによるクリップの結果を表示します。
CHOOSEFONT cf; /* コモンダイアログボックス構造体 */
LOGFONT lf; /* 論理フォント構造体 */
HFONT hfont; /* 新しい論理フォントハンドル */
HFONT hfontOld; /* 古い論理フォントハンドル */
HDC hdc; /* デバイスコンテキスト */
int nXStart, nYStart; /* 描画座標 */
RECT rc; /* RECT構造体 */
SIZE sz; /* テキストの大きさを受け取るSize構造体 */
double aflSin[90]; /* 0〜90度のサインの値 */
double aflCos[90]; /* 0〜90度のコサインの値 */
double flRadius,a; /* 円の半径 */
int iMode; /* クリッピングモード */
HRGN hrgn; /* リージョンハンドル */
LRESULT APIENTRY MainWndProc(
HWND hwnd, /* Windowハンドル */
UINT message, /* メッセージ */
WPARAM wParam, /* wPalam */
LPARAM lParam) /* lParam */
{
PAINTSTRUCT ps;
switch (message) {
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
EndPaint(hwnd, &ps);
break;
case WM_COMMAND: //メニューからの起動
switch (wParam) {
case IDM_VANISH: //クライアントエリアのクリア
hdc = GetDC(hwnd);
GetClientRect(hwnd, &rc);
FillRect(hdc, &rc, GetStockObject(WHITE_BRUSH));
ReleaseDC(hwnd, hdc);
break;
case IDM_AND: //クリッピングモードを RGN_AND にセットする
iMode = RGN_AND;
break;
case IDM_COPY: //クリッピングモードを RGN_COPY にセットする
iMode = RGN_COPY;
break;
case IDM_DIFF: //クリッピングモードを RGN_DIFF にセットする
iMode = RGN_DIFF;
break;
case IDM_OR: //クリッピングモードを RGN_OR にセットする
iMode = RGN_OR;
break;
case IDM_XOR: //クリッピングモードを RGN_XOR にセットする
iMode = RGN_XOR;
break;
case IDM_CLIP_PATH:
//windowにキャッシュされたDCを検索
hdc = GetDC(hwnd);
//Choose Fontダイアログで、
//ユーザーによって求められたフォントから論理フォントを作成し、
//デバイスコンテキストにそのフォントを選択する。
hfont = CreateFontIndirect(cf.lpLogFont);
hfontOld = SelectObject(hdc, hfont);
//テキストに合った大きさのRECTを得る
GetTextExtentPoint(hdc, "Clip Path", 9, &sz);
//クリッピング領域のセット
hrgn = CreateRectRgn(nXStart, nYStart,
nXStart + sz.cx,
nYStart + sz.cy);
SelectClipRgn(hdc, hrgn);
//ユーザーの選択したフォントで描かれたテキストをから、クリップパスを作る。
BeginPath(hdc);
TextOut(hdc, nXStart, nYStart, "Clip Path", 9);
EndPath(hdc);
SelectClipPath(hdc, iMode);
/* 0〜90度のサインを計算 */
for (i = 0; i < 90; i++) {
aflSin[i] = sin( (((double)i) / 180.0) * 3.14159);
}
/* 0〜90度のコサインを計算 */
for (i = 0; i < 90; i++) {
aflCos[i] = cos( (((double)i) / 180.0) * 3.14159);
}
/* Set the radius value. */
flRadius = (double)(2 * sz.cx);
//半径から円のエッジまで拡張して、光状線を引く。
for (i = 0; i < 90; i++) {
MoveToEx(hdc, nXStart, nYStart, (LPPOINT) NULL);
LineTo(hdc, nXStart + ((int) (flRadius * aflCos[i])),
nYStart + ((int) (flRadius * aflSin[i])));
}
//フォントを元に戻す
SelectObject(hdc, hfontOld);
//ユーザーフォントの削除
DeleteObject(hfont);
//DCのリリース
ReleaseDC(hwnd, hdc);
break;
case IDM_FONT:
//必要メンバの初期化
cf.lStructSize = sizeof (CHOOSEFONT);
cf.hwndOwner = hwnd;
cf.lpLogFont = &lf;
cf.Flags = CF_SCREENFONTS | CF_EFFECTS;
cf.rgbColors = RGB(0, 255, 255);
cf.nFontType = SCREEN_FONTTYPE;
//Fontダイアログ・ボックスの表示。
//ユーザーによるフォントの選択。
//その選択でテキストを描画出来るようにする。
if (ChooseFont(&cf)) {
hdc = GetDC(hwnd);
hfont = CreateFontIndirect(cf.lpLogFont);
hfontOld = SelectObject(hdc, hfont);
crOld = SetTextColor(hdc, cf.rgbColors);
TextOut(hdc, nXStart, nYStart, "Clip Path", 9);
SetTextColor(hdc, crOld);
SelectObject(hdc, hfontOld);
DeleteObject(hfont);
ReleaseDC(hwnd, hdc);
}
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
break;
case WM_DESTROY: //windowの終了
PostQuitMessage(0);
break;
default: //それら以外なら
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
}