问题描述
我在 win32 api 中有一个对话框.我有一个静态元素,如下所示.
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;
在对话框过程中,我使用 WM_PAINT 和以下代码处理它.
In the dialog proc I handle it using WM_PAINT With following Code.
HWND ErrorMessage = GetDlgItem(hwndDlg, ID_ERROR_MSG);
和
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);
我想在它周围绘制红色边框.我尝试使用 DrawEdge() 但边缘只有黑色.此外,它有点3D效果.我想做类似的事情:
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.
有人可以帮忙吗?
推荐答案
我要处理的方法是将静态控件子类化.这样做意味着您只需专注于实现您想要的不同行为,而不是整个控件的行为/逻辑.
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.
首先,您需要告诉 windows 您正在这样做.接下来您需要为窗口实现一个 WndProc(实际上是一个 SUBCLASSPROC)函数.最后,您需要进行绘画.
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.
这是一个粗略的例子:
#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);
}
这篇关于WINAPI:静态对话框项的彩色边框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!