问题
I have a dialog box in win32 api. I have a Static Element which has been created as below.
lpw = lpwAlign(lpw); // Align DLGITEMTEMPLATE on DWORD boundary
lpdit = (LPDLGITEMTEMPLATE)lpw;
lpdit->x = 12;
lpdit->y = 36;
lpdit->cx = 75;
lpdit->cy = 7;
lpdit->id = ID_ERROR_MSG;
lpdit->style = WS_CHILD | SS_BITMAP | WS_VISIBLE ;
lpw = (LPWORD)(lpdit + 1);
*lpw++ = 0xFFFF;
*lpw++ = 0x0082; // Static class
lpwsz = (LPWSTR)lpw;
nchar = MultiByteToWideChar(CP_ACP, 0, errorMsg.c_str(), -1, lpwsz, 50);
lpw += nchar;
*lpw++ = 0;
In the dialog proc I handle it using WM_PAINT With following Code.
HWND ErrorMessage = GetDlgItem(hwndDlg, ID_ERROR_MSG);
and
hdc = BeginPaint(ErrorMessage, &ps_Confirm);
hFont = CreateFont(18,0,0,0,FW_BOLD,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_OUTLINE_PRECIS,
CLIP_DEFAULT_PRECIS,CLEARTYPE_QUALITY, VARIABLE_PITCH,TEXT("Arial"));
SelectObject(hdc, hFont);
wchar_t sCaption[100];
GetWindowText(ErrorMessage,sCaption, 100);
//Sets the coordinates for the rectangle in which the text is to be formatted.
SetRect(&rect, 0,0,75,7);
SetTextColor(hdc, RGB(0,0,0));
SetBkColor(hdc, RGB(255,255,255));
//SetBkMode(hdc, TRANSPARENT);
DrawText(hdc, sCaption, -1,&rect, DT_NOCLIP);
DeleteObject(hFont);
EndPaint(ErrorMessage, &ps_Confirm);
I want to have red border drawn around it. I tried using DrawEdge() but the edge is only of black color. Also, It is a bit in 3D effect. I wanted to do something like :
One hack I can do is to draw a blank static with dark red color and then another static element with white color over it. But it is not a very good solution.
Can somebody help?
回答1:
The way I'd go about this is to subclass the static control. Doing so means you only need to concentrate on implementing the different behaviour that you want, rather than the entirety of a control's behaviour/logic.
First, you need to tell windows that you're doing it. Next you need to implement a WndProc (actually a SUBCLASSPROC) function for the window. Finally, you need to do the painting.
Here's a rough example:
#define _WIN32_WINNT 0x0501 // min version for subclassing funcs
#include <windows.h>
#include <commctrl.h>
#include <stdio.h>
#include "resource.h"
HINSTANCE hInst;
const int errorPanelSubclassId = 1;
LRESULT paintErrorPanel(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
hdc = BeginPaint(hWnd, &ps);
RECT mRect;
GetClientRect(hWnd, &mRect);
HBRUSH redBrush = CreateSolidBrush( RGB(255,0,0) );
FrameRect(hdc, &mRect, redBrush);
DeleteObject(redBrush);
EndPaint(hWnd, &ps);
return 0;
}
LRESULT CALLBACK subclassedWinProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
if (uMsg == WM_PAINT)
{
paintErrorPanel(hWnd, wParam, lParam);
return 0;
}
else
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}
BOOL CALLBACK DlgMain(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_INITDIALOG:
{
HWND errorPanel = GetDlgItem(hwndDlg, IDC_ERROR_STATIC);
SetWindowSubclass(errorPanel, subclassedWinProc, errorPanelSubclassId, NULL);
}
return TRUE;
case WM_CLOSE:
{
EndDialog(hwndDlg, 0);
}
return TRUE;
case WM_DESTROY:
{
RemoveWindowSubclass(errorPanel, subclassedWinProc, errorPanelSubclassId);
}
return 0;
case WM_COMMAND:
{
switch(LOWORD(wParam))
{
}
}
return TRUE;
}
return FALSE;
}
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
hInst=hInstance;
InitCommonControls();
return DialogBox(hInst, MAKEINTRESOURCE(DLG_MAIN), NULL, (DLGPROC)DlgMain);
}
来源:https://stackoverflow.com/questions/28738658/winapi-colored-border-for-static-dialog-item