C ++ Win32静态控件透明背景 [英] C++ Win32 Static Control Transparent Background
问题描述
解决方案:如下所述,最好为文本创建自己的方法,而不是试图让控件行为异常。因此,为此创建自定义控件将是最好的。我找到了一个教程,解释这一切:消息,请参阅此SO回答 中的代码 - 如果窗口有在绘制文本时,我们需要对静态控件进行子类化并使用透明背景模式:
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{MSG msg;
WNDCLASS w;
hInst = hInstance;
memset(& w,0,sizeof(WNDCLASS));
w.style = CS_HREDRAW | CS_VREDRAW;
w.lpfnWndProc = WndProc;
w.hInstance = hInst;
w.hbrBackground = CreateHatchBrush(HS_DIAGCROSS,RGB(255,0,0));
w.lpszClassName = L我的班级;
w.hCursor = LoadCursor(NULL,IDC_ARROW);
RegisterClass(& w);
HWND hWndWindow = CreateWindow(LMy Class,LMy title,WS_OVERLAPPEDWINDOW,300,200,800,600,NULL,NULL,hInst,NULL);
ShowWindow(hWndWindow,nCmdShow);
UpdateWindow(hWndWindow);
while(GetMessage(& msg,NULL,0,0))
{TranslateMessage(& msg);
DispatchMessage(& msg);
}
DeleteObject(w.hbrBackground);
return msg.wParam;
}
WNDPROC StaticWndProc = NULL;
TCHAR szText [] = _T(TestString);
LRESULT CALLBACK MyStaticWndProc(HWND hwnd,UINT Message,WPARAM wparam,LPARAM lparam)
{if(Message == WM_PAINT)
{RECT rc;
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd,& ps);
GetClientRect(hwnd,& rc);
SetBkMode(hdc,TRANSPARENT);
DrawText(hdc,szText,_tcslen(szText),& rc,DT_CENTER | DT_VCENTER);
EndPaint(hwnd,& ps);
return 0;
}
// v2 StaticWndProc(hwnd,Message,wparam,lparam);
return callWindowProc(StaticWndProc,hwnd,Message,wparam,lparam); // v2
}
HWND hWndStatic; // v2
LONG WINAPI WndProc(HWND hwnd,UINT Message,WPARAM wparam,LPARAM lparam)
{switch(Message)
{case WM_CREATE:
{LRESULT lRes = DefWindowProc hwnd,Message,wparam,lparam);
hWndStatic = CreateWindowEx(0,LStatic,NULL,WS_CHILD | WS_VISIBLE | SS_LEFT,10,130,200,40,hwnd,NULL,hInst,NULL); // v2 deleted HWND
StaticWndProc =(WNDPROC)SetWindowLong(hWndStatic,GWL_WNDPROC,(LPARAM)MyStaticWndProc);
return lRes;
}
case WM_DESTROY:
SetWindowLong(hWndStatic,GWL_WNDPROC,(LPARAM)StaticWndProc); // v2
PostQuitMessage(0);
break;
默认值:
return DefWindowProc(hwnd,Message,wparam,lparam);
}
return 0;
}
Solution: As said below, it is probably better to create your own method for the text, instead of trying to get the control to behave abnormally. So, creating a custom control for this would be best. I found a tutorial that explains it all: http://www.codeproject.com/Articles/559385/Custom-Controls-in-Win-API-The-Basics .
This has been asked, no practical solutions though.
I am trying to use static controls to show text so updating is as easy as just sending a message. I can just as easily scratch the controls and just use plain DrawText() but it seems like a "sloppier" solution.
this is the owner draw method.
else if (message == WM_DRAWITEM) {
LPDRAWITEMSTRUCT pDIS;
pDIS = (LPDRAWITEMSTRUCT)lParam;
RECT rc;
SetTextColor(pDIS->hDC, RGB(200,10,60));
SelectObject(pDIS->hDC, (HPEN)GetStockObject(NULL_PEN));
SelectObject(pDIS->hDC, (HBRUSH)GetStockObject(NULL_BRUSH));
SetBkMode(pDIS->hDC, TRANSPARENT);
// Start Drawing
Rectangle(pDIS->hDC, 0, 0, pDIS->rcItem.right+1, pDIS->rcItem.bottom+1);
DrawText(pDIS->hDC, "teststring", 10, &pDIS->rcItem, 0);
return 0;
}
and I get:
Left is what I get, right is what I want.
CreateWindow("STATIC", "teststring", WS_CHILD | WS_VISIBLE | SS_OWNERDRAW, 20, 20, 120, 40, hwnd, (HMENU)(IDC_STATIC_TEST), GetModuleHandle(NULL), NULL);
That is what I use to create the static.
I have spent well over 4 hours on and off trying to do this, I have tried everything.
Any help is appreciated.
Would it be better to just forget the static controls and fall back on just using DrawText().
Thanks.
// create window
hwnd = CreateWindowEx (0, szClassName, "Test Transparent Static Main Window", WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX , 100, 100, 300, 200, HWND_DESKTOP, NULL, hThisInstance, NULL);
ShowWindow (hwnd, nFunsterStil);
// set globals
hWnd = hwnd;
hInstance = hThisInstance;
// main window message loop
while (GetMessage (&messages, NULL, 0, 0)) {
TranslateMessage(&messages);
DispatchMessage(&messages);
}
return messages.wParam;
}
// Main Window Procedure
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
// local variables
PAINTSTRUCT ps;
HDC hdc;
switch (message) {
case WM_CREATE:
{
LRESULT lRes = DefWindowProc(hwnd, message, wParam, lParam);
HWND hWndStatic = CreateWindowEx(0, "Static", NULL, WS_CHILD | WS_VISIBLE, 10, 10, 200, 100, hwnd, NULL, hInstance, NULL);
StaticWndProc = (WNDPROC)SetWindowLong(hWndStatic, GWL_WNDPROC, (LPARAM)MyStaticWndProc);
return lRes;
}
break;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
SetBkMode(hdc, TRANSPARENT);
SetBkColor(hdc, RGB(110,110,110));
EndPaint(hwnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
}
LRESULT CALLBACK MyStaticWndProc(HWND hwnd, UINT Message, WPARAM wparam, LPARAM lparam) {
if (Message == WM_PAINT) {
RECT rc;
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &rc);
SetBkMode(hdc, TRANSPARENT);
SetTextColor(hdc, RGB(0,100,200));
DrawText(hdc, "TESTTEXT", 8, &rc, DT_CENTER | DT_VCENTER | SS_LEFT);
EndPaint(hwnd, &ps);
return 0;
}
return StaticWndProc(hwnd, Message, wparam, lparam);
}
---------EDIT---------------------------------------------------------
No need to do Owner Draw, you can just use <-- this will not work if the window has a pattern background, we need to subclass the static control and use the transparent background mode while drawing the text:SetWindowText()
and handle the WM_CTLCOLORSTATIC message, see the code in this SO Answer
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{ MSG msg;
WNDCLASS w;
hInst = hInstance;
memset(&w,0,sizeof(WNDCLASS));
w.style = CS_HREDRAW | CS_VREDRAW;
w.lpfnWndProc = WndProc;
w.hInstance = hInst;
w.hbrBackground = CreateHatchBrush(HS_DIAGCROSS, RGB(255, 0, 0));
w.lpszClassName = L"My Class";
w.hCursor = LoadCursor(NULL, IDC_ARROW);
RegisterClass(&w);
HWND hWndWindow = CreateWindow(L"My Class", L"My title", WS_OVERLAPPEDWINDOW, 300, 200, 800, 600, NULL, NULL, hInst, NULL);
ShowWindow(hWndWindow, nCmdShow);
UpdateWindow(hWndWindow);
while(GetMessage(&msg, NULL, 0, 0))
{ TranslateMessage(&msg);
DispatchMessage(&msg);
}
DeleteObject(w.hbrBackground);
return msg.wParam;
}
WNDPROC StaticWndProc = NULL;
TCHAR szText[] = _T("TestString");
LRESULT CALLBACK MyStaticWndProc(HWND hwnd, UINT Message, WPARAM wparam, LPARAM lparam)
{ if (Message == WM_PAINT)
{ RECT rc;
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &rc);
SetBkMode(hdc, TRANSPARENT);
DrawText(hdc, szText, _tcslen(szText), &rc, DT_CENTER | DT_VCENTER);
EndPaint(hwnd, &ps);
return 0;
}
//v2 StaticWndProc(hwnd, Message, wparam, lparam);
return return CallWindowProc(StaticWndProc, hwnd, Message, wparam, lparam); //v2
}
HWND hWndStatic; //v2
LONG WINAPI WndProc(HWND hwnd, UINT Message, WPARAM wparam, LPARAM lparam)
{ switch (Message)
{ case WM_CREATE:
{ LRESULT lRes = DefWindowProc(hwnd, Message, wparam, lparam);
hWndStatic = CreateWindowEx(0, L"Static", NULL, WS_CHILD| WS_VISIBLE |SS_LEFT, 10, 130, 200, 40, hwnd, NULL, hInst, NULL); //v2 deleted HWND
StaticWndProc = (WNDPROC) SetWindowLong(hWndStatic, GWL_WNDPROC, (LPARAM)MyStaticWndProc);
return lRes;
}
case WM_DESTROY:
SetWindowLong(hWndStatic, GWL_WNDPROC, (LPARAM)StaticWndProc); //v2
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, Message, wparam, lparam);
}
return 0;
}
这篇关于C ++ Win32静态控件透明背景的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!