NSIS:如何实现带复选框的嵌入式ListView标题文本背景透明
Hey there! Let's work through this transparency issue for your ListView header created with the embeddedLists.dll plugin. The code you tried targets the ListView control directly, but the header is actually a separate child control inside the ListView—so that's probably why your current approach isn't working. Here's how to fix it:
Step 1: Get the ListView Header Handle
First, you need to retrieve the handle of the header control nested inside your ListView. Use the LVM_GETHEADER message to do this:
; Define required message constants at the top of your script !define LVM_GETHEADER 0x101F !define HDM_SETBKCOLOR 0x1201 ; Assuming you already have the ListView handle stored in $0 (from your existing GetDlgItem call) SendMessage $0 ${LVM_GETHEADER} 0 0 $1 ; $1 now holds the header control's handle
Step 2: Set Header Transparency/Background Color
With the header handle in hand, try these approaches to make its background transparent:
Option 1: Use SetCtlColors on the Header Handle
Apply the transparency setting directly to the header control instead of the ListView:
SetCtlColors $1 "FFFFFF" "transparent"
If "transparent" doesn't behave as expected, match the parent window's background color instead:
; Get the main dialog's background color GetCtlColors $HWNDPARENT $parentBkColor $parentTxtColor SetCtlColors $1 "FFFFFF" $parentBkColor
Option 2: Send HDM_SETBKCOLOR to the Header
Explicitly set the header's background color to match the parent using the HDM_SETBKCOLOR message:
; Use the parent window's background color retrieved earlier SendMessage $1 ${HDM_SETBKCOLOR} 0 $parentBkColor
Option 3: Subclass the Header Control (For Stubborn Cases)
If the above methods fail (some custom ListView implementations override drawing), subclass the header to skip background erasure. You'll need the NSIS System plugin for this:
!include "System.nsh" ; Define the subclass callback function Function HeaderSubclassCallback ; Retrieve the original window procedure System::Call 'user32::GetWindowLongPtr(i $hWnd, i -21)i .r$oldProc' ; Skip background erasure by handling WM_ERASEBKGND ${If} $uMsg == ${WM_ERASEBKGND} Return 1 ; Tell Windows we handled the erase, no need to draw a background ${EndIf} ; Pass other messages to the original procedure System::Call 'user32::CallWindowProc(i $oldProc, i $hWnd, i $uMsg, i $wParam, i $lParam)i .r$ret' Return $ret FunctionEnd ; Apply the subclass after getting the header handle ($1) System::Call 'user32::SetWindowLongPtr(i $1, i -21, i HeaderSubclassCallback)i .r$oldHeaderProc'
Quick Verification Checks
- Double-check with WinSpy++ that your
GetDlgItemcall targets the correct ListView control (ID 1211). - Confirm
$HWNDPARENTpoints to the correct parent dialog window.
内容的提问来源于stack exchange,提问作者Suneel Yadav

