You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NSIS按钮颜色修改问题:仅边框变色,求完整修改代码

NSIS按钮完整颜色修改解决方案

Windows系统默认会给按钮应用主题视觉样式,直接使用SetCtlColors只能修改按钮的文字和边框颜色,无法改变主题按钮的背景色。以下是两种可行的解决方法:

方法一:禁用按钮主题样式(简单快捷)

通过禁用按钮的系统主题,让SetCtlColors可以完全控制按钮的文字和背景色,缺点是按钮会回到经典Windows样式(无圆角等主题效果)。

!include "MUI2.nsh"
!include "nsDialogs.nsh"
OutFile "Test.exe"

!define MUI_WELCOMEPAGE_TITLE "Welcome to the Example Installer"
!define MUI_WELCOMEPAGE_TEXT "This is an example NSIS installer."

!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE "English"

; 导入SetWindowTheme函数用于禁用控件主题
!ifndef SetWindowTheme
    !define SetWindowTheme "comctl32::SetWindowTheme"
!endif

Section
    nsDialogs::Create 1018
    Pop $0

    ${NSD_CreateButton} 7u 10u 100u 12u "My Button"
    Pop $1
    
    ; 禁用按钮的系统主题
    ${SetWindowTheme} $1 "" ""
    ; 设置按钮文字为黑色,背景为绿色
    SetCtlColors $1 0x000000 0x00FF00
    ${NSD_OnClick} $1 MyButtonClick

    ${NSD_CreateNumber} 10U 25% 100u 12u "Message Here"
    Pop $2
    SetCtlColors $2 0x00FF00 0x000000  ; 设置数值控件颜色

    nsDialogs::Show
SectionEnd

Function MyButtonClick
    MessageBox MB_OK "按钮被点击了"
FunctionEnd

方法二:自绘按钮(完全自定义)

通过设置按钮为自绘样式(BS_OWNERDRAW),手动处理按钮的绘制逻辑,可完全自定义背景、文字、边框颜色,同时能灵活控制按钮样式。

!include "MUI2.nsh"
!include "nsDialogs.nsh"
!include "WinMessages.nsh"
OutFile "Test.exe"

!define MUI_WELCOMEPAGE_TITLE "Welcome to the Example Installer"
!define MUI_WELCOMEPAGE_TEXT "This is an example NSIS installer."

!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE "English"

; 定义自绘按钮的颜色常量
!define BTN_BG_COLOR 0x00FF00
!define BTN_TEXT_COLOR 0x000000
!define BTN_BORDER_COLOR 0x000000

Section
    nsDialogs::Create 1018
    Pop $0

    ; 创建按钮并设置为自绘样式
    ${NSD_CreateButton} 7u 10u 100u 12u "My Button"
    Pop $1
    SendMessage $1 ${BM_SETSTYLE} ${BS_OWNERDRAW} 1
    ${NSD_OnClick} $1 MyButtonClick

    ; 绑定WM_DRAWITEM消息处理函数,负责绘制按钮
    nsDialogs::OnMessage ${WM_DRAWITEM} OnDrawItem

    ${NSD_CreateNumber} 10U 25% 100u 12u "Message Here"
    Pop $2
    SetCtlColors $2 0x00FF00 0x000000  ; 设置数值控件颜色

    nsDialogs::Show
SectionEnd

Function MyButtonClick
    MessageBox MB_OK "按钮被点击了"
FunctionEnd

; WM_DRAWITEM消息处理函数:自定义绘制按钮
Function OnDrawItem
    Exch $0
    Exch
    Exch $1
    Push $2
    Push $3
    Push $4
    Push $5
    Push $6
    Push $7

    ; 获取DRAWITEMSTRUCT结构体数据
    System::Call "*$1(p.r2, i.r3, i.r4, i.r5, i.r6, i.r7, p.r8, p.r9, p.r10)"
    ; 校验是否为目标按钮控件
    StrCmp $2 $1 0 Done
    StrCmp $4 ${ODT_BUTTON} 0 Done

    ; 绘制按钮背景
    System::Call "gdi32::CreateSolidBrush(i ${BTN_BG_COLOR})i.r11"
    System::Call "user32::FillRect(p $8, p $9, p $11)"
    System::Call "gdi32::DeleteObject(p $11)"

    ; 绘制按钮边框
    System::Call "gdi32::CreatePen(i 0, i 1, i ${BTN_BORDER_COLOR})i.r11"
    System::Call "gdi32::SelectObject(p $8, p $11)i.r12"
    System::Call "user32::FrameRect(p $8, p $9, p $11)"
    System::Call "gdi32::SelectObject(p $8, p $12)"
    System::Call "gdi32::DeleteObject(p $11)"

    ; 设置文字绘制属性
    System::Call "gdi32::SetTextColor(p $8, i ${BTN_TEXT_COLOR})"
    System::Call "gdi32::SetBkMode(p $8, i 1)" ; 透明背景

    ; 获取按钮文字并居中绘制
    System::Call "user32::GetWindowText(p $2, t.r13, i 256)"
    System::Call "user32::DrawText(p $8, t r13, i -1, p $9, i 0x000DT_CENTER|0x000DT_VCENTER|0x000DT_SINGLELINE)"

Done:
    Pop $7
    Pop $6
    Pop $5
    Pop $4
    Pop $3
    Pop $2
    Pop $1
    Pop $0
    Return
FunctionEnd

内容的提问来源于stack exchange,提问作者Jerlin Cs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 18:17:42