WINAPI: Colored Border for Static Dialog Item

匆匆过客 提交于 2021-02-10 12:58:34

问题


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 :

red border

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.

enter image description here

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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!