《Windows API每日一练》8.3 scrollbar控件

news2024/11/20 11:21:34

在第三章SYSMETS2.C实例中,我们是通过CreateWindow函数创建窗口的参数窗口样式中添加垂直或水平滚动条。本节我们将讲述作为子窗口控件的滚动条。

本节必须掌握的知识点:

        滚动条类

        滚动条控件和着色

8.3.1 滚动条类

窗口滚动条与滚动条控件的异同

滚动条子窗口控件可以出现在父窗口客户区的任何地方。可以使用预定义的“滚动条”窗口类和两种滚动条样式SBS_VERT 和SBS_HORZ之一来创建子窗口滚动条控件。

不同于按钮控件,滚动条控件不发送 WM_COMMAND消息到父窗口。它们就像窗口滚动条一样发送WM_VSCROLL和 WM_HSCROLL消息。在处理滚动条消息时,可以用IParam参数区分窗口滚动条和滚动条控件。如果IParam参数等于0,就说明它是窗口滚动条;如果等于滚动条窗口句柄,就说明它是滚动条控件。wParam参数的高位字和低位字部分对于窗口滚动条和滚动条控件的含义是一样的。

与窗口滚动条有一个固定的宽度不同,Windows会通过CreateWindow调用(或之后的 MoveWindow调用)中指定的矩形尺寸来调整滚动条控件的尺寸。你可以产生长而窄的滚动 条控件或短而粗的滚动条控件。

如果想创建和窗口滚动条具有相同尺寸的滚动条控件,则可以使用GetSystemMetrics 获得水平滚动条的高度:

GetSyscemMetrics (SM_CYHSCROLL) ;

或者获得垂直滚动条的宽度:

GetSystemMetrics (SM_CXVSCROLL);

滚动条窗口样式标识符 SBS_LEFTALIGN,SBS_RIGHTALIGN,SBS_TOPALIGN 和 SBS_BOTTOMALIGN都为滚动条提供标准尺寸。不过它们只适用于对话框中的滚动条。 可以使用与用于窗口滚动条同样的函数来设置滚动条控件的范围和位置:

SeCScrollRange (hwndScroll, SB_CTL, iMin, iMax, bRedraw) ;

SetScrollPos (hwndScroll, SB_CTL, iPos, bRedraw) ;

SetScrollInfo (hwndScroll, SB_CTL, &si, bRedraw);

区别在于,窗口滚动条会使用主窗口的句柄作为第一个参数,SB_VERT或SB_HORZ作 为第二个参数。

更神奇的是,名为COLOR_SCROLLBAR的系统颜色不再对滚动条起作用。滚动条两端的按钮及滑块的颜色将基于COLOR_BTNFACE,COLOR_BTNHILIGHT ,COLOR_BTNSHADOW,COLOR_BTNTEXT (给小箭头用),COLOR_DKSHADOW 以及 COLOR_BTNLIGHT。在两端按钮之间的大片区域则基于COLOR_BTNFACE和 COLOR_BTNHIGHLIGHT 的某种组合。

如果你俘获了 WM_CTLCOLORSCROLLBAR消息,就可以从这个消息返回一个画刷来修改原来的颜色。

窗口滚动条

滚动条控件

消息

发送WM_VSCROLLWM_HSCROLL消息。不发送WM_COMMAND消息。wParam参数的意义是一样的。lParam:当消息来自窗口滚动条时为NULL,来自滚动条控件时为滚动条的句柄。

宽度或高度

固定大小

//水平滚动条高度

GetSysMetricsSM_CYHSCROLL;

//垂直滚动条宽度

GetSysMetricsSM_CYVSCROLL

1、大小、位置均可设定;

2、在CreateWindowMoveWindow函数中指定,大小可自定义。

窗口样式

WS_VSCROLL:垂直滚动条(在窗口右侧)

WS_HSCROLL:水平滚动条(在窗口下方)

可用滚动条样式和尺寸

SBS_VERTSBS_HORZ

S SBS_TOPALIGN  BS_BOTTOMALIGNSBS_LEFTALIGNSBS_RIGHTALIGN等。

调用函数

的参数

SetScrollInfo(hwnd,SB_VERT,

&si,bRedraw);

SetScrollInfo(hwndScroll,SB_CTL,

&si,bRedraw);

自动键盘接口

滚动条控件还可以处理按键信息,但前提是它们拥有输入焦点。下表显示了键盘光标是如何转换为滚动条消息的。

光标键

滚动条消息wParam

Home

SB_TOP

End

SB_BOTTOM

PageUp

SB_PAGEUP

PageDown

SB_PAGEDOWN

←或↑

SB_LINEUP

→或↓

SB_LINEDOWN

事实上,SB_TOP和SB_BOTTOM这两个滚动条消息只能通过键盘产生。如果你想让滚动条控件在鼠标单击滚动条时取得输入焦点,必须在CreateWindow函数的窗口类参数中加入WS_TABSTOP标识符。当滚动条获得输入焦点时,滚动条滑块上会显示一个闪烁的灰色块。

为了给滚动条提供完整的键盘接口,需要做更多的工作。首先,WndProc窗口过程必须专门提供滚动条所需要的输入焦点。为此,它会处理WM_SETFOCUS消息,这是父窗口得到输入焦点时接收到的消息。WndProc只需把输入焦点给其中一个滚动条:

SetFocus (hwndScroll[idFocus]);

这里的idFocus是一个全局变量。

但还需要一些方法通过键盘把输入焦点从一个滚动条移到另一个,最好是使用Tab键。 这样做会有一定难度,因为一旦滚动条获得输入焦点,它就会处理所有的按键信息。但是滚动条关心的只有光标键,它会忽视Tab键。解决这个问题的出路在于使用“窗口子类” 这一技术。

8.3.2 第52练:滚动条控件和着色

/*------------------------------------------------------------------

052  WIN32 API 每日一练

     第52个例子COLORS1.C:滚动条控件和着色

     CallWindowProc 函数

     SetWindowLong函数

     SetClassLong函数

     GetDlgItem 函数

     WM_CTLCOLORSCROLLBAR消息

     WM_CTLCOLORSTATIC 消息

     WM_SYSCOLORCHANGE消息

(c) www.bcdaren.com, 2020

----------------------------------------------------------------*/

#include <windows.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

LRESULT CALLBACK ScrollProc(HWND, UINT, WPARAM, LPARAM);

int idFocus;

WNDPROC OldScroll[3];

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

    PSTR szCmdLine, int iCmdShow)

{

    static TCHAR szAppName[] = TEXT("Colors1");

    (略)

    return msg.wParam;

}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM

    lParam)

{

    static COLORREF crPrim[3] = { RGB(255, 0, 0), RGB(0, 255, 0),

    RGB(0, 0, 255) };

    static HBRUSH hBrush[3], hBrushStatic; //三个滚动条的背景画刷

    static HWND hwndScroll[3], hwndLabel[3], hwndValue[3], hwndRect;

    static int color[3], cyChar; //三个滚动条当前的颜色值

    static RECT rcColor;

    static TCHAR * szColorLabel[] = { TEXT("Red"), EXT("Green"),TEXT("Blue") };

    HINSTANCE hInstance;

    int i, cxClient, cyClient;

    TCHAR szBuffer[10];

    switch (message)

    {

    case WM_CREATE:

        hInstance = (HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE);//获取进程句柄

        //创建白色矩形静态窗口控件ID:9--用来存放3个滚动条,可以隐掉后测试

        hwndRect = CreateWindow(TEXT("static"), NULL, //生成一个静态矩形

            WS_CHILD | WS_VISIBLE | SS_WHITERECT,//白色背景静态窗口类

            0, 0, 0, 0,

            hwnd, (HMENU)9, hInstance, NULL);

        for (i = 0; i < 3; i++) //生成3个滚动条控件

        {

            //创建三个滚动条,范围0-255,ID分别为0,1,2

//WS_TABSTOP标识符:当滚动条获得输入焦点时,

//滚动条滑块上会显示一个闪烁的灰色块。

            hwndScroll[i] = CreateWindow(TEXT("scrollbar"), NULL,

                WS_CHILD | WS_VISIBLE |

                WS_TABSTOP | SBS_VERT//垂直滚动条窗口类

                0, 0, 0, 0,

                hwnd, (HMENU)i, hInstance, NULL);

            //SB_CTL检索滚动条控件的位置

//设置滚动条控件的滚动范围

            SetScrollRange(hwndScroll[i], SB_CTL, 0, 255, FALSE);

            SetScrollPos(hwndScroll[i], SB_CTL, 0, FALSE); //滚动滑块位置

            //3个颜色名称为"Red"、"Green"、"Blue"的静态文本框,ID分别为3,4,5

            hwndLabel[i] = CreateWindow(TEXT("static"), szColorLabel[i],

                WS_CHILD | WS_VISIBLE | SS_CENTER, //将文本居中

                0, 0, 0, 0,

                hwnd, (HMENU)(i + 3),

                hInstance, NULL);

            //3个表示颜色值得静态文本框,初始值为"0",IDs 6, 7, and 8

            hwndValue[i] = CreateWindow(TEXT("static"), TEXT("0"),

                WS_CHILD | WS_VISIBLE | SS_CENTER,

                0, 0, 0, 0,

                hwnd, (HMENU)(i + 6),

                hInstance, NULL);

            //为滚动条设置一个新的窗口过程ScrollProc,返回旧的窗口过程地址

            OldScroll[i] = (WNDPROC)SetWindowLong(hwndScroll[i],

                GWL_WNDPROC, (LONG)ScrollProc);

            //创建3个画刷

            hBrush[i] = CreateSolidBrush(crPrim[i]);

        }

        //创建静态文本背景画刷,3D 显示元素的高亮颜色

        hBrushStatic = CreateSolidBrush(GetSysColor(COLOR_BTNHIGHLIGHT));

       //获取对话框字体的高

        cyChar = HIWORD(GetDialogBaseUnits());

        return 0;

    case WM_SIZE:

        cxClient = LOWORD(lParam);

        cyClient = HIWORD(lParam);

        //设置右侧显式颜色的矩形框坐标

        SetRect(&rcColor, cxClient / 2, 0, cxClient, cyClient);

        //指定的矩形尺寸来调整白色矩形静态窗口控件的尺寸

        MoveWindow(hwndRect, 0, 0, cxClient / 2, cyClient, TRUE);

        //设置滚动条在主窗口大小和位置:宽cxClient/14,高cyClient -4*cyChar;

        for (i = 0; i < 3; i++)

        {

            MoveWindow(hwndScroll[i],

                (2 * i + 1) * cxClient / 14, 2 * cyChar,

                cxClient / 14, cyClient - 4 * cyChar, TRUE);

            MoveWindow(hwndLabel[i],

                (4 * i + 1) * cxClient / 28, cyChar / 2,

                cxClient / 7, cyChar, TRUE);

            MoveWindow(hwndValue[i],

                (4 * i + 1) * cxClient / 28,

                cyClient - 3 * cyChar / 2,

                cxClient / 7, cyChar, TRUE);

        }

        SetFocus(hwnd);

        return 0;

    case WM_SETFOCUS:

        SetFocus(hwndScroll[idFocus]);//设置为焦点控件

        return 0;

    case WM_VSCROLL:

        //获取子窗口ID

        i = GetWindowLong((HWND)lParam, GWL_ID);

        switch (LOWORD(wParam))

        {

        case SB_PAGEDOWN: color[i] += 15;

            //继续执行

        case SB_LINEDOWN: color[i] = min(255, color[i] + 1); break;

        case SB_PAGEUP: color[i] -= 15;

            // 继续执行

        case SB_LINEUP: color[i] = max(0, color[i] - 1); break;

        case SB_TOP: color[i] = 0; break;

        case SB_BOTTOM: color[i] = 255; break;

        case SB_THUMBPOSITION:

        case SB_THUMBTRACK: color[i] = HIWORD(wParam); break;

        defaultbreak;

        }

        SetScrollPos(hwndScroll[i], SB_CTL, color[i], TRUE); //设置滑块位置

        wsprintf(szBuffer, TEXT("%i"), color[i]); //改变颜色值

        SetWindowText(hwndValue[i], szBuffer); //显示颜色值

       //设置窗口类的背景颜色

       //创建新画刷替换窗口类结构中的黑色画刷

        DeleteObject((HBRUSH) //删除旧画刷

            SetClassLong(hwnd, GCL_HBRBACKGROUND, (LONG) //替换背景画刷

                CreateSolidBrush(RGB(color[0], color[1], color[2]))));

        InvalidateRect(hwnd, &rcColor, TRUE); //重绘窗口,TRUE擦除背景

        //UpdateWindow(hwnd);//立即更新,不需要送入消息队列

        return 0;

        //将要绘制控件时滚动条控件消息:

//wParam:滚动条控件的设备上下文的句柄DC,lParam:滚动条句柄

    case WM_CTLCOLORSCROLLBAR:

        //返回画刷句柄,用来修改三个滚动条内部的颜色

        i = GetWindowLong((HWND)lParam, GWL_ID);//获取控件ID

//必须将句柄返回给画刷。 系统使用画刷绘制滚动条控件的背景。

        return (LRESULT)hBrush[i];

   //将要绘制时,静态控件消息---设定静态文本的颜色

    case WM_CTLCOLORSTATIC:

        i = GetWindowLong((HWND)lParam, GWL_ID); //获取窗口ID

        if (i >= 3 && i <= 8) // 6个static text controls ID:3~8

        {

            //设置静态文本颜色

            SetTextColor((HDC)wParam, crPrim[i % 3]);

//设置系统颜色为背景色

            SetBkColor((HDC)wParam, GetSysColor(COLOR_BTNHIGHLIGHT));

            return (LRESULT)hBrushStatic;

        }

        break;

        //更改系统颜色

    case WM_SYSCOLORCHANGE:

        DeleteObject(hBrushStatic);//删除画刷

//重新创建画刷

        hBrushStatic = CreateSolidBrush(GetSysColor(COLOR_BTNHIGHLIGHT));

        return 0;

    case WM_DESTROY:

        //创建新的白色画刷,把句柄存入到窗口类中然后删除旧的画刷

        DeleteObject((HBRUSH)

            SetClassLong(hwnd, GCL_HBRBACKGROUND, (LONG)

                GetStockObject(WHITE_BRUSH)));

        for (i = 0; i < 3; i++)

            DeleteObject(hBrush[i]);

        DeleteObject(hBrushStatic);

        PostQuitMessage(0);

        return 0;

    }

    return DefWindowProc(hwnd, message, wParam, lParam);

}

//窗口子类过程

LRESULT CALLBACK ScrollProc(HWND hwnd, UINT message,

    WPARAM wParam, LPARAM lParam)

{

    int id = GetWindowLong(hwnd, GWL_ID);

    switch (message)

    {

        //收到按键消息时,更改输入焦点到另一个滚动条

    case WM_KEYDOWN:

        if (wParam == VK_TAB)

            SetFocus(GetDlgItem(GetParent(hwnd),//包含控件的对话框的句柄

           //追踪SHIFT键,改变TAB键切换的顺序:

           //按下SHIFT <0:2,1,0;未按下>0:0,1,2

            (id + (GetKeyState(VK_SHIFT) < 0 ? 2 : 1)) % 3));

        break;

    case WM_SETFOCUS:

        idFocus = id;

        break;

    }

    //调用子窗口旧的窗口过程

    return CallWindowProc(OldScroll[id], hwnd, message, wParam, lParam);

}

/******************************************************************************

CallWindowProc 函数:子窗口类过程返回旧窗口过程

LRESULT CallWindowProcA(

  WNDPROC lpPrevWndFunc,

  HWND    hWnd,

  UINT    Msg,

  WPARAM  wParam,

  LPARAM  lParam

);

*******************************************************************************

SetWindowLong函数:设置子窗口类过程

LONG SetWindowLongA(

  HWND hWnd,

  int  nIndex,//设置窗口过程的新地址

  LONG dwNewLong//新窗口过程

);

*******************************************************************************

SetClassLong函数:将指定偏移量处的指定32位(long)值替换到指定窗口所属类的额外类存储器或WNDCLASSEX结构中。

DWORD SetClassLongA(

  HWND hWnd,   //窗口的句柄,间接地,窗口所属的类。

  int  nIndex, //将要被替换的值。

  LONG dwNewLong//替换值

);

注意  此函数已被SetClassLongPtr函数取代。要编写与Windows 32位和64位版本兼容的代码,请使用SetClassLongPtr。

*******************************************************************************

GetDlgItem 函数用于获取对话框模板中标识符(ID)对应的子窗口句柄。

HWND GetDlgItem(

  HWND hDlg,    //对话框的窗口句柄

  int  nIDDlgItem//子窗口的标识符(ID)

);

返回值:对应标识符的子窗口的句柄(HWND)。

*******************************************************************************

WM_CTLCOLORSCROLLBAR消息:发送滚动条控件消息至父窗口

wParam:DC,lParam:滚动条句柄,

//必须返回画笔句柄

WM_CTLCOLORSTATIC 消息:发送静态控件消息至父窗口

WM_SYSCOLORCHANGE消息:更改系统颜色设置后,会将WM_SYSCOLORCHANGE消息发送到所有顶级窗口

*/

       运行结果:

图8-5 滚动条控件

 

总结

实例COLORS1.C在一个白色静态文本框内绘制了3个滚动条控件,此外还绘制了6个静态文本控件显示RGB颜色及颜色值。在主窗口客户区的左侧绘制一个矩形,使用3个滚动条控件的RGB值创建一个画刷,填充矩形背景。

此外,还根据3个滚动条控件的值(0~255)分别创建3个画刷,设置3个静态文本颜色,创建一个高亮系统颜色画刷作为静态文本控件的背景色。

实例COLORS1.C还创建了一个窗口子类,定义了一个新的滚动条子窗口控件过程,用于处理键盘接口TAB键,切换焦点窗口。

主窗口过程对于WM_CREATE消息的处理。首先创建一个存放3个滚动条控件的静态文本框。接着创建3个滚动条控件,并将滚动条滚动范围设置为0~255,与RGB颜色值对应。初始滚动条滑块位置为0。然后在滚动条控件的上方和下方分别创建3个静态文本控件,用于显示RGB颜色和颜色值。最后调用SetWindowLong函数设置滚动条控件新的窗口过程ScrollProc,并返回Windows预定义的滚动条控件默认窗口过程,存入OldScroll[i]数组。接着创建一个静态文本背景画刷,并获取对话框字体的高。

WM_SIZE消息的处理:调用SetRect函数在主窗口右侧绘制一个矩形框。调用MoveWindow函数调整静态文本框控件和滚动条控件的大小。

WM_SETFOUCUS消息处理:调用SetFocus函数将当前idFocus滚动条控件设为焦点窗口。

WM_VSCROLL消息处理:调用GetWindowLong函数获取滚动条控件ID,并依据wParam

参数低字值调整滚动条滑块位置。滑块位置即颜色值,修改3个静态文本颜色值,并以此生成新画刷填充主窗口右侧矩形背景色。

WM_CTLCOLORSCROLLBAR消息处理:将要绘制滚动条控件时接收此消息,该消息的wParam:滚动条控件的设备上下文的句柄DC;lParam:滚动条句柄。调用GetWindowLong依据滚动条控件句柄获取滚动条控件ID,并返回画刷return (LRESULT)hBrush[ID];

WM_CTLCOLORSTATIC消息处理:将要绘制静态文本控件时接收此消息,调用GetWindowLong依据静态文本控件句柄获取控件ID,并更新静态文本颜色和颜色值。

WM_SYSCOLORCHANGE消息处理:如果更改系统颜色,则删除旧静态文本背景画刷,重新依据系统颜色生成新的静态文本背景画刷。

WM_DESTROY消息处理:删除创建的新GDI画刷对象。

窗口子类

滚动条控件的窗口过程在Windows内部。但是你可以调用GetWindowLong来获取这 个窗口过程的地址,使用GWL_WNDPROC标识符作为参数即可。此外,还可以通过调用SetWindowLong,为滚动条设置一个新的窗口过程。这种技术被称为“窗口子类”。它的功能非常强大。它可以让你连接到已有的窗口过程,在你的程序中处理一些消息,并将其他消息传递给旧的窗口过程。

在COLORS1中,能初步处理滚动条消息的窗口过程名为ScroMProc,它列在 C0L0RS1.C文件的结束部分。由于COLORS1中的ScrollProc是一个被Windows调用的函数,因此它必须被定义成CALLBACK类型。

对这三个滚动条中的每一个COLORS1都使用SetWindowLong来设置新的滚动条窗口过程的地址,同时获得现有滚动条窗口过程的地址:

OldScroll[i] = (WNDPROC) SetWindowLong (hwndScroll[i),

GWL_VMDPROC,(LONG) ScrollProc));

现在,ScrollProc获得了 Windows发送给COLORS1程序中三个滚动条的所有消息(当然不包括在其他程序中的滚动条)。当它收到Tab或Shift-Tab击键信息后,此ScrollProc 窗口过程只需更改输入焦点到下一个(或前一个)滚动条即可。它使用CallWindowProc来调 用旧的滚动条窗口过程。

背景着色

在COLORS1定义它的窗口类时,给它的客户区指定了一个黑色的背景画刷:

wndclass.hbrBackground = CreateSolidBrush (0);

当你更改COLORS1的滚动条设置时,程序必须创建一个新的画刷,并把新画刷句柄存入窗口类的结构中。正如我们使用GetWindowLong和SetWindowLong来获取和设置滚动 条窗口过程一样,我们可以使用GetClassWord和SetClassWord来获取和设置这个画刷的句柄。

你可以创建新的画刷,把句柄存入到窗口类结构中,然后删除旧的画刷:

DeleteObject ((HBRUSH)

              SetClassLong (hwnd, GCL_HBRBACKGROUND, (LONG)

                     CreaceSolidBrush (RGB (colort[0], color[1], color[2]))));

下一次Windows重新给窗口背景着色的时候,Windows将使用这个新画刷。如果要强制 Windows擦除背景,我们可以让客户区的右半部分失效:

InvalidateRect (hwnd, &rcColor, TRUE);

函数的第三个参数输入TRUE(非零值),表明我们希望在窗口重绘之前擦除背景。

InvalidateRect函数会让Windows把WM_PAINT消息放在窗口过程的消息队列中。由于WM_PAINT消息属于低优先级消息。因此,如果你仍然在移动鼠标或光标键,此消息将不会立即被处理。另一种情况是,如果你希望窗口在颜色修改后立即更新,则可以在 InvalidateRect函数被调用后调用下面的函数:

UpdateWindow (hwnd);

不过,这个函数可能会拖慢键盘和鼠标处理速度。

COLORS1的WndProc函数不直接处理WM_PAINT消息,而是将它传递给 DefWindowProc函数。WM_PAINT消息在Windows中的默认处理方式仅仅是调用 BeginPaint和EndPaint来使窗口有效。因为我们在InvalidateRect中指定旧背景应该被删除,所以调用BeginPaint会使Windows产生一条WM_ERASEBKGND(擦除背景)消息。 WndProc也会忽略此消息。Windows会对该消息进行处理,它使用窗口类指定的画刷来擦除这个客户区的背景。

通常情况下,在终止程序前进行清理总是一个不错的好主意,因此在处理 WM_DESTROY消息时,DeleteObject被再次调用:

DeleteObject ((HBRUSH)

       SetClassLong (hwnd, GCL_HBRBACKGROUND,

              (LONG) GetStockObject (WHITE_BRUSH)));

给滚动条和静态文本着色

在COLORS1中,三个滚动条内部和六个文本框中文本的颜色分别被着色为红色、绿色和蓝色。滚动条的着色是通过处理WM_CTLCOLORSCROLLBAR消息来完成的。

在WndProc中,为三个画刷句柄定义了一个静态数组:

static HBRUSH hBrush [3];

在处理WM_CREATE的过程中,创建了这三个画刷:

for (i = 0;i < 3; i++)

hBrush[0] = CreateSolidBrush (crPrim [i]) ;

在这里crPrim数组中包含三个基色的RGB值。在处理WM_CTLCOLORSCROLLBAR

时,窗口过程返回三个画刷中的一个:

case WM_CTLCOLORSCROLLBAR:

i = GetWindowLong ((HWND) IParam, GWL_ID);

             return (LRESULT) hBrush [i];

这些画刷必须在处理WM_DESTROY消息期间被销毁:

for (i =0; i < 3; i++)

       DeleteObject (hBrush [i]));

类似地,静态文本框中文本的着色是通过处理WM_CTLCOLORSTATIC消息和调用 SetTextCoIor函数完成的。文本的背景通过调用SetBkColor设置为系统颜色 COLOR_BTNHIGHLIGHT。这会导致文本的背景与滚动条后面的静态矩形控件具有相同的颜色。对于静态文本控件,这种文本的背景颜色只应用于字符串中每个字符背后的矩形框,而不是控件窗口的整个宽度。要做到这一点,窗口过程必须返回一个COLOR_BTNHIGHLIGHT颜色的画刷句柄。这个被称为hBrushStatic的画刷是在 WM_CREATE处理期间产生的,并在WM_DESTROY消息处理期间被销毁。

程序在WM_CREATE消息处理期间产生COLOR_BTNHIGHLIGHT颜色的画刷,并在程序生命周期中使用它。但这样我们会碰到一个小问题。如果C0L0R_BTNHIGHL1GHT 颜色在程序运行过程中被改变了,静态矩形的颜色会改变,文本背景颜色会改变,但整个文本窗口控件的背景仍将保持原有的COLOR_BTNHIGHLIGHT颜色。

为解决这一问题,COLORS 1在处理WM_SYSCOLORCHANGE消息时简单地用新颜色重新创建hBrushStatic。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1899548.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第一百四十八节 Java数据类型教程 - Java字符串搜索和Java子字符串

Java数据类型教程 - Java字符串搜索 我们可以使用indexOf()和lastIndexOf()方法获取另一个字符串中的字符或字符串的索引。例如 public class Main {public static void main(String[] args) {String str new String("Apple");int index str.indexOf("p"…

YOLOv8数据集可视化[目标检测实践篇]

先贴代码,后面再补充解析。 这个篇章主要是对标注好的标签进行可视化,虽然比较简单,但是可以从可视化代码中学习到YOLOv8是如何对标签进行解析的。 下面直接贴代码: import cv2 import numpy as np import osdef read_det_labels(label_file_path):with open(labe…

C++初学者指南-4.诊断---用gdb调试

C初学者指南-4.诊断—用gdb调试 幻灯片 gdb / 前端 gdbGNU的命令行调试器cgdb基于终端的gdb前端Linux安装:sudo apt-get install cgdbgdbgui基于浏览器的gdb前端网址&#xff1a;https://gdbgui.com/安装&#xff1a;sudo pip install gdbguiQt Creator可以连接gdbVisual St…

Vite: 近几个版本的更新

概述 在 2021 年 2 月&#xff0c;尤大正式推出了 Vite 2.0 版本&#xff0c;可以说是 Vite 的一个重要转折点&#xff0c;自此之后 Vite 的用户量发生了非常迅速的增长&#xff0c;很快达到了每周 100 万的 npm 下载量。同时&#xff0c;Vite 的社区也越来越活跃&#xff0c;…

实验3-Spark基础-Spark的安装

文章目录 1. 下载安装 Scala1.1 下载 Scala 安装包1.2 基础环境准备1.3 安装 Scala 2. 下载安装 Spark2.1 下载 Spark 安装包2.2 安装 Spark2.3 配置 Spark2.4 创建配置文件 spark-env.sh 3. pyspark 启动4. 建立/user/spark文件夹 1. 下载安装 Scala 1.1 下载 Scala 安装包 下…

Redis 八股文

标题 1. Redis主从同步原理&#xff1a;判断下线的条件:故障转移如何保证Sentinel高可用 1. Redis主从同步原理&#xff1a; 1、slave执行命令向master建立连接 2、master执行bgsave&#xff08;后台存储&#xff09;&#xff0c;生成rdb快照&#xff08;redis备份方式&#x…

基于STM32F407ZG的FreeRTOS移植

1.从FreeRTOS官网中下载源码 2、简单分析FreeRTOS源码目录结构 2.1、简单分析FreeRTOS源码根目录 &#xff08;1&#xff09;Demo&#xff1a;是官方为一些单片机移植FreeRTOS的例程 &#xff08;2&#xff09;License&#xff1a;许可信息 &#xff08;3&#xff09;Sourc…

如何使用C++调用Pytorch模型进行推理测试:使用libtorch库

如何使用C调用Pytorch模型进行推理测试&#xff1a;使用libtorch库 目录 如何使用C调用Pytorch模型进行推理测试&#xff1a;使用libtorch库一、环境准备1&#xff0c;linux&#xff1a;以ubuntu 22.04系统为例1. 准备CUDA和CUDNN2. 准备C环境3, 下载libtorch文件4, 编写测试li…

开发者评测|操作系统智能助手OS Copilot

操作系统智能助手OS Copilot 文章目录 操作系统智能助手OS CopilotOS Copilot 是什么优势功能 操作步骤创建实验重置密码创建Access Key配置安全组安装 os-copilot环境变量配置功能评测命令行模式多轮交互模式 OS Copilot 产品体验评测反馈OS Copilot 产品功能评测反馈 参考文档…

【鸿蒙学习笔记】Stage模型工程目录

官方文档&#xff1a;应用配置文件概述&#xff08;Stage模型&#xff09; 目录标题 FA模型和Stage模型工程级目录模块级目录app.json5module.json5程序执行流程程序基本结构开发调试与发布流程 FA模型和Stage模型 工程级目录 模块级目录 app.json5 官方文档&#xff1a;app.j…

【笔记】记一次在linux上通过在线安装mysql报错 CentOS 7 的官方镜像已经不再可用的解决方法+mysql配置

报错&#xff08;恨恨恨恨恨恨恨&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff09;&#xff1a; [rootlocalhost ~]# sudo yum install mysql-server 已加载插件&#xff1a;fastestmirror, langpacks Determining fastest mirrors Could not retrie…

MWC上海展 | 创新微MinewSemi携ME54系列新品亮相Nordic展台

6月28日&#xff0c; 2024MWC上海圆满落幕&#xff0c;此次盛会吸引了来自全球124个国家及地区的近40,000名与会者。本届大会以“未来先行&#xff08;Future First&#xff09;”为主题&#xff0c;聚焦“超越5G”“人工智能经济”“数智制造”三大子主题&#xff0c;探索讨论…

AI语音工具——Fish Speech:使用简单,可训练专属语音模型!

今天给大家介绍一款超好用的AI语音工具——Fish Speech&#xff0c;使用简单&#xff0c;还可以训练自己的语音模型&#xff01; 工具介绍 Fish Speech是由 Fish Audio 开发的免费开源文本转语音模型。经过十五万小时的数据训练&#xff0c;Fish Speech能够熟练掌握中文、日语…

【Docker系列】Docker 镜像构建中的跨设备移动问题及解决方案

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

前端实现无缝自动滚动动画

1. 前言: 前端使用HTMLCSS实现一个无缝滚动的列表效果 示例图: 2. 源码 html部分源码: <!--* Author: wangZhiyu <w3209605851163.com>* Date: 2024-07-05 23:33:20* LastEditTime: 2024-07-05 23:49:09* LastEditors: wangZhiyu <w3209605851163.com>* File…

数据分析:基于STAR+FeatureCounts的RNA-seq分析全流程流程

流程主要包含两部分组成&#xff1a; 第一部分&#xff1a;二代测序数据的Raw data的fastq文件转换成Gene Count或者Features Counts表&#xff08;行是Features&#xff0c;列是样本名&#xff09;&#xff1b;第二部分&#xff1a;对counts 表进行统计分析&#xff0c;并对其…

印尼网络安全治理能力观察

在全国国际机场的移民服务完全瘫痪 100 多个小时后&#xff0c;印尼政府承认其新成立的国家数据中心 (PDN) 遭受了网络攻击。 恶意 Lockbit 3.0 勒索软件加密了存储在中心的重要数据&#xff0c;其背后的黑客组织要求支付 800 万美元的赎金。 不幸的是&#xff0c;大多数数据…

纸电混合阶段,如何在线上实现纸电会档案的协同管理?

随着国家政策的出台和引导&#xff0c;电子会计档案的管理越来越规范&#xff0c;电子会计档案建设成为打通财务数字化最后一公里的重要一环。但是&#xff0c;当前很多企业的财务管理仍处于电子档案和纸质档案并行的阶段&#xff0c;如何能将其建立合理清晰关联&#xff0c;统…

Hugging Face 全球政策负责人首次参加WAIC 2024 前沿 AI 安全和治理论坛

Hugging Face 全球政策负责人艾琳-索莱曼 &#xff08; Irene Solaiman &#xff09;将参加7月5日在上海举办的WAIC-前沿人工智能安全和治理论坛&#xff0c;并在现场进行主旨演讲和参加圆桌讨论。具体时间信息如下&#xff1a;主旨演讲&#xff1a;开源治理的国际影响时间 &am…

Spring框架Mvc(2)

1.传递数组 代码示例 结果 2.集合参数存储并进行存储类似集合类 代码示例 postman进行测试 &#xff0c;测试结果 3.用Json来对其进行数据的传递 &#xff08;1&#xff09;Json是一个经常使用的用来表示对象的字符串 &#xff08;2&#xff09;Json字符串在字符串和对象…