今回、ライブラリでプログラムをしていると色々と制約が出てきたので
ライブラリなしでコードを書こうと思い
Win32APiに移植をしていると
なんだか色々と問題が起きてしまいました
そのなかで、大した問題でないように思えて原因が全然つかめなかったので
質問させていただきます
テキストを描画したのですが、なぜか文字の後ろに白い四角が描画されてしまい
テキストのみを描画することができません
...というか、何が原因で透過できていないのかさっぱりです
以下はテキストを描画している場所のコードとその描画先ウィンドウと親ウィンドウです
(関数名とか主仕様ですので見逃してくださいw)
BOOL InitApp(HINSTANCE hInst, WNDPROC WndProc, LPCWSTR szClassName)
{
WNDCLASS wc;
//プロシージャ名
wc.cbCls Extra = 0; //禁止単語回避
wc.cbWndExtra = 0;
wc.hInstance = hInst; //インスタンス
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL; //メニュー名
wc.lpszClassName = (LPCWSTR)szClassName;
return (RegisterClass(&wc));
}
// 文字描画(変数引数可)
void PrintMessage(HDC hdc,LPCWSTR lpchText,int x,int y)
{
HFONT hf01;
static LOGFONT lf01;
ZeroMemory(&lf01,sizeof(lf01));
lf01.lfCharSet=DEFAULT_CHARSET;
lf01.lfQuality=ANTIALIASED_QUALITY;
_tcscpy(lf01.lfFaceName,_T("メイリオ"));
hf01=CreateFontIndirect(&lf01);
//HGDIOBJ hOldOBj = SelectObject(hdc, hFont);
RECT rc = { x , y , 24*wcslen(lpchText) , 36 };
SetTextColor(hdc, RGB(0,0,0));
//SetBkColor(hdc, RGB(0xff,0xff,0xff));
//SetBkMode(hdc, OPAQUE);
DrawText(hdc, lpchText, -1, &rc, DT_LEFT);
SelectObject(hdc, hf01);
//TextOut( hdc, x, y, lpchText, (int)_tcslen(lpchText) );
DeleteObject( hf01 );
}
BOOL InitInstance(HINSTANCE hInstance)
{
HWND hWnd;
hInst = hInstance; // グローバル変数にインスタンス処理を格納します。
hWnd = CreateWindowEx(WS_EX_LAYERED | WS_EX_TOPMOST, szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
// タスクバーにボタンを表示したくない場合は、次のようにする
//hWnd = CreateWindowEx(WS_EX_LAYERED | WS_EX_TOPMOST | WS_EX_TOOLWINDOW, szWindowClass, szTitle, WS_POPUP,
// CW_USEDEFAULT, 0, uWidth, uHeight, NULL, NULL, hInstance, NULL);
if (!hWnd) {
return FALSE;
}
// 文字描画用のウィンドウを生成
// 位置はメインウィンドウと同じ位置で
RECT rc;
GetWindowRect(hWnd, &rc);
ghMojiWindow = CreateWindowEx(WS_EX_LAYERED | WS_EX_TOPMOST | WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT,
szWindowClass2, szTitle2, WS_POPUP,
rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, hWnd, NULL, hInstance, NULL);
if (!ghMojiWindow) {
return FALSE;
}
ShowWindow(hWnd, SW_SHOWNORMAL);
UpdateWindow(hWnd);
ShowWindow(ghMojiWindow, SW_SHOWNORMAL);
UpdateWindow(ghMojiWindow);
// テスト的に文字を描画してみる
HDC hdc = GetDC(ghMojiWindow);
PrintMessage(hdc,_T("SetupInstance...Step1 - Check Through ...Okay"),10,10);
ReleaseDC(ghMojiWindow, hdc);
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) {
case WM_CREATE:
{
// PNGファイルを読み出しておく
FILE *fp = _tfopen(_T("AIS_MainSerface700x500.png"), _T("rb"));
if (fp == NULL) {
MessageBox(hWnd, _T("AIS_MainSerface700x500.pngが開けません。"), _T("エラー"), MB_OK | MB_ICONSTOP);
DestroyWindow(hWnd);
break;
}
// メモリに読み込んだpngファイルを、ビットマップハンドルにする
hBitmap = LoadPngFromFile(hWnd, fp, uWidth, uHeight);
if (hBitmap == NULL) {
fclose(fp);
MessageBox(hWnd, _T("test_ulw.pngをPNGファイルとして読み込めませんでした。"), _T("エラー"), MB_OK | MB_ICONSTOP);
DestroyWindow(hWnd);
break;
}
fclose(fp);
// ウィンドウの形状をビットマップに合わせて変更
SetWindowPos(hWnd, 0, 0, 0, uWidth, uHeight, SWP_NOMOVE | SWP_NOZORDER);
// ==========================
// レイヤードウィンドウの設定
// ==========================
// 各種デバイスコンテキストの取得
HDC hmemdc, hdc, hsdc;
hsdc = GetDC(0); // デスクトップのデバイスコンテキスト(色情報指定用)
hdc = GetDC(hWnd); // このウィンドウのデバイスコンテキスト
hmemdc = CreateCompatibleDC(hdc); // hdcの互換デバイスコンテキスト
POINT wndPos;
SIZE wndSize;
RECT rc;
// レイヤードウィンドウの画面位置とサイズ
GetWindowRect(hWnd, &rc);
wndPos.x = rc.left;
wndPos.y = rc.top;
wndSize.cx = uWidth;
wndSize.cy = uHeight;
// デバイスコンテキストにおけるレイヤの位置
POINT po;
po.x = po.y = 0;
// レイヤードウィンドウの指定
BLENDFUNCTION blend;
blend.BlendOp = AC_SRC_OVER;
blend.BlendFlags = 0;
blend.SourceConstantAlpha = 255; // 不透明度(レイヤードウィンドウ全体のアルファ値)
blend.AlphaFormat = AC_SRC_ALPHA;
// 画像を描画をする
HGDIOBJ hOldObj = SelectObject(hmemdc, hBitmap);
BitBlt(hdc, 0, 0, uWidth, uHeight, hmemdc, 0, 0, SRCCOPY|CAPTUREBLT); // レイヤードウィンドウではCAPTUREBLTが必要
// レイヤードウィンドウの位置、サイズ、形、内容、透明度を更新
if (0 == UpdateLayeredWindow(hWnd, hsdc, &wndPos, &wndSize, hmemdc, &po, 0, &blend, ULW_ALPHA)) {
TCHAR strErrMes[80];
DWORD err = GetLastError();
wsprintf(strErrMes, _T("UpdateLayeredWindow失敗:エラーコード=%d"), err);
MessageBox(hWnd, strErrMes, _T("エラー"), MB_OK | MB_ICONSTOP);
DestroyWindow(hWnd);
}
SelectObject(hmemdc, hOldObj);
DeleteDC(hmemdc);
ReleaseDC(hWnd, hdc);
ReleaseDC(0, hsdc);
}
break;
case WM_NCHITTEST: // ウィンドウ上のどこをマウスで掴んでも、位置を移動できるようにする
return HTCAPTION;
case WM_TIMER:
break;
case WM_MOVING: // 文字描画用ウィンドウにも同様のメッセージを伝える
{
LPRECT prc = (LPRECT)lParam;
MoveWindow(ghMojiWindow, prc->left, prc->top, prc->right - prc->left, prc->bottom - prc->top, FALSE);
}
break;
case WM_DESTROY:
if (hBitmap)
DeleteObject(hBitmap);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// 文字描画ウィンドウ用のウィンドウプロシージャ。基本的に何もしない。
LRESULT CALLBACK WndProc2(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) {
case WM_CREATE:
// 文字描画用ウィンドウはビットマップのサイズに合わせる
SetWindowPos(ghMojiWindow, 0, 0, 0, uWidth, uHeight, SWP_NOMOVE | SWP_NOZORDER);
// 子ウィンドウの白部分は通過色に
SetLayeredWindowAttributes(hWnd, RGB(0xff, 0xff, 0xff), 255, LWA_COLORKEY | LWA_ALPHA);
// 標準フォントの取得
//hFont = (HFONT)GetStockObject(SYSTEM_FONT);
hInst = ((LPCREATESTRUCT)lParam)->hInstance;
InitApp(hInst, AIS_Main_WinProc, _T("child"));
hChdWnd = CreateWindowW(_T("child"),
_T(" - Icais ver.01A-NANA - "),//タイトルバーにこの名前が表示されます
WS_SYSMENU | WS_THICKFRAME | WS_CAPTION | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_EX_TOOLWINDOW, //ウィンドウの種類
CW_USEDEFAULT, //X座標
CW_USEDEFAULT, //Y座標
800, //幅
600, //高さ
hWnd, //親ウィンドウのハンドル、親を作るときはNULL
(HMENU)NULL, //メニューハンドル、子供のID
hInst, //インスタンスハンドル
NULL);
ShowWindow(hChdWnd, SW_SHOW);
UpdateWindow(hChdWnd);
break;
case WM_CLOSE: // 突然の終了禁止
return 0;
default:
return DefWindowProc( hWnd, message, wParam, lParam );
}
return 0;
}
LRESULT CALLBACK AIS_Main_WinProc(HWND hwnd,UINT message,WPARAM wparam,LPARAM lparam)
{
static char text[] = "Iris CreativeEntertaimentTalkSystem Type-A ProperName-NANA...";
static char *p=text;
static wchar_t pp;
static wchar_t ppp[256];
static int c=0;
switch(message)
{
case WM_CREATE:
if(SetTimer(hwnd, ID_MYTIMER, 3, NULL) == 0)
{
}
else
{
}
break;
case WM_TIMER:
if(c>=_mbstrlen((const char*)text)){
KillTimer(hwnd, ID_MYTIMER);
}else{
KillTimer(hwnd, ID_MYTIMER);
SetTimer(hwnd, ID_MYTIMER, 3, NULL);
cw_change(&pp,2,p);
wcscat(ppp,&pp);
++p;
c++;
InvalidateRect(hwnd,NULL,NULL);
}
break;
case WM_NCHITTEST: // ウィンドウ上のどこをマウスで掴んでも、位置を移動できるようにする
return HTCAPTION;
break;
case WM_DESTROY: /* ウインドウの後処理 */
AIS_Main_DestroyProc();
break;
case WM_PAINT:
HBRUSH hBrush;
PAINTSTRUCT ps;
HDC hdc;
hdc=BeginPaint(hwnd,&ps);
RECT rc;
GetClientRect(hwnd,&rc);
hBrush = CreateSolidBrush(RGB(176,224,230));
FillRect(hdc,&rc,hBrush);
DeleteObject(hBrush);
EndPaint(hwnd, &ps);
PrintMessage(GetDC(hwnd),ppp,10,10);
break;
default:
return DefWindowProc(hwnd,message,wparam,lparam);
}
return 0L;
}
wc.cbCls Extra = 0; ←引っかかったので禁止単語回避してます
環境は
VS2005 C++
ライブラリなし・・・なのか?(Win32APIとかともいうらしい・・・まだそんなに詳しくないです)
WinXP HomeSP3