可以在 NSIS 中绘制到 window,如何声明类型的 WinAPI 变量?
Possible to paint to window in NSIS, How to declare WinAPI variable of type?
是否可以在 NSIS 中绘制静态控件?如果是,我该如何声明变量,例如 PAINTSTRUCT
等?我可以在常规 C 中轻松完成此操作,但使用 NSIS 和汇编类型语言让我很困惑。
下面我正在尝试在静态控件上绘制边框:
Var MainWndSubProc
Function MainWndSubProc
${If} = ${WM_DRAWITEM}
# I'm assuming = the WPARAM and = LPARAM?
$LOWORD $R0 # get id of window we are painting
${If} $R0 == $myStaticId
# C code which works: how to translate to NSIS 'assembly'?
HDC hdc;
PAINTSTRUCT ps;
hdc = BeginPaint(args.hwnd, &ps);
RECT mRect;
GetClientRect(args.hwnd, &mRect);
HBRUSH brush = CreateSolidBrush(RGB(50, 50, 50));
HPEN pen = CreatePen(PS_SOLID, 5, RGB(191, 191, 191));
SelectObject(hdc, pen);
SelectObject(hdc, brush);
Rectangle(hdc, 0, 0, mRect.right, mRect.bottom);
DeleteObject(pen);
DeleteObject(brush);
EndPaint(args.hwnd, &ps);
# NSIS translation
# how to declare PAINTSTRUCT
$LOWORD $R0
System::Call `user32::BeginPaint(i $R0, i R1)`
.. ?
${EndIf}
${EndIf}
FunctionEnd
Function MyGUIInit
${WndSubclass_Subclass} $HWNDPARENT MainWndSubProc $MainWndSubProc $MainWndSubProc
FunctionEnd
<= 64 位的类型在普通 NSIS 变量中存储为字符串。对于较大的类型,您需要使用系统插件结构语法:
OutFile test.exe
RequestExecutionLevel user
Page InstFiles
!include WinMessages.nsh
!include nsDialogs.nsh
!include LogicLib.nsh
!include Colors.nsh
!include WndSubclass.nsh
Var MainWndSubProc
Var hStaticCtrl
Function MainWndSubProc
${If} = ${WM_DRAWITEM}
System::Call '*(i,i,i,i,i,i.r5,i.r6,i,i,i.r8,i.r9)' ; Get HWND, HDC and size from DRAWITEMSTRUCT
${If} $hStaticCtrl =
System::Call 'GDI32::CreateSolidBrush(i 0x2277ee)i.s' ; Just made up a color here
System::Call 'GDI32::SelectObject(ir6,is)i.s'
${RGB} 191 191 191
System::Call 'GDI32::CreatePen(i${PS_SOLID}, i5, i "0x")i.s'
System::Call 'GDI32::SelectObject(ir6,is)i.s'
System::Call 'GDI32::Rectangle(ir6, i0, i0, ir8, ir9)'
System::Call 'GDI32::SelectObject(ir6,is)i.s'
System::Call 'GDI32::DeleteObject(is)'
System::Call 'GDI32::SelectObject(ir6,is)i.s'
System::Call 'GDI32::DeleteObject(is)'
${EndIf}
${EndIf}
FunctionEnd
Function .onGUIInit
; Your example failed to show how you create the static control so I'm forced to just create one here at run-time
GetDlgItem [=10=] $hwndparent 2 ; Find cancel button so we can put our control there
ShowWindow [=10=] 0
System::Call '*(i,i,i,i)i.r1'
System::Call 'USER32::GetWindowRect(ir0,ir1)'
System::Call 'USER32::MapWindowPoints(i0,i$hwndparent,ir1,i2)'
System::Call '*(i.r4,i.r5,i.r6,i.r7)'
System::Free
IntOp -
IntOp -
System::Call 'USER32::CreateWindowEx(i0, t "Static", i0, i${WS_CHILD}|${WS_VISIBLE}|${SS_OWNERDRAW}, ir4, ir5, ir6, ir7, i$hwndparent, i0, i0, i0)i.r0'
StrCpy $hStaticCtrl [=10=]
${WndSubclass_Subclass} $HWNDPARENT MainWndSubProc $MainWndSubProc $MainWndSubProc
FunctionEnd
Section
SectionEnd
你的 C 代码质量让我相信你还没有准备好编写这种代码。如果您查看 DRAWITEMSTRUCT 的文档,您会看到 hDC 成员的评论:"this device context must be used when performing drawing operations on the control." 但您决定调用 BeginPaint
!您也无法恢复 DC,并且删除了选择到 DC 中但不允许的对象。
是否可以在 NSIS 中绘制静态控件?如果是,我该如何声明变量,例如 PAINTSTRUCT
等?我可以在常规 C 中轻松完成此操作,但使用 NSIS 和汇编类型语言让我很困惑。
下面我正在尝试在静态控件上绘制边框:
Var MainWndSubProc
Function MainWndSubProc
${If} = ${WM_DRAWITEM}
# I'm assuming = the WPARAM and = LPARAM?
$LOWORD $R0 # get id of window we are painting
${If} $R0 == $myStaticId
# C code which works: how to translate to NSIS 'assembly'?
HDC hdc;
PAINTSTRUCT ps;
hdc = BeginPaint(args.hwnd, &ps);
RECT mRect;
GetClientRect(args.hwnd, &mRect);
HBRUSH brush = CreateSolidBrush(RGB(50, 50, 50));
HPEN pen = CreatePen(PS_SOLID, 5, RGB(191, 191, 191));
SelectObject(hdc, pen);
SelectObject(hdc, brush);
Rectangle(hdc, 0, 0, mRect.right, mRect.bottom);
DeleteObject(pen);
DeleteObject(brush);
EndPaint(args.hwnd, &ps);
# NSIS translation
# how to declare PAINTSTRUCT
$LOWORD $R0
System::Call `user32::BeginPaint(i $R0, i R1)`
.. ?
${EndIf}
${EndIf}
FunctionEnd
Function MyGUIInit
${WndSubclass_Subclass} $HWNDPARENT MainWndSubProc $MainWndSubProc $MainWndSubProc
FunctionEnd
<= 64 位的类型在普通 NSIS 变量中存储为字符串。对于较大的类型,您需要使用系统插件结构语法:
OutFile test.exe
RequestExecutionLevel user
Page InstFiles
!include WinMessages.nsh
!include nsDialogs.nsh
!include LogicLib.nsh
!include Colors.nsh
!include WndSubclass.nsh
Var MainWndSubProc
Var hStaticCtrl
Function MainWndSubProc
${If} = ${WM_DRAWITEM}
System::Call '*(i,i,i,i,i,i.r5,i.r6,i,i,i.r8,i.r9)' ; Get HWND, HDC and size from DRAWITEMSTRUCT
${If} $hStaticCtrl =
System::Call 'GDI32::CreateSolidBrush(i 0x2277ee)i.s' ; Just made up a color here
System::Call 'GDI32::SelectObject(ir6,is)i.s'
${RGB} 191 191 191
System::Call 'GDI32::CreatePen(i${PS_SOLID}, i5, i "0x")i.s'
System::Call 'GDI32::SelectObject(ir6,is)i.s'
System::Call 'GDI32::Rectangle(ir6, i0, i0, ir8, ir9)'
System::Call 'GDI32::SelectObject(ir6,is)i.s'
System::Call 'GDI32::DeleteObject(is)'
System::Call 'GDI32::SelectObject(ir6,is)i.s'
System::Call 'GDI32::DeleteObject(is)'
${EndIf}
${EndIf}
FunctionEnd
Function .onGUIInit
; Your example failed to show how you create the static control so I'm forced to just create one here at run-time
GetDlgItem [=10=] $hwndparent 2 ; Find cancel button so we can put our control there
ShowWindow [=10=] 0
System::Call '*(i,i,i,i)i.r1'
System::Call 'USER32::GetWindowRect(ir0,ir1)'
System::Call 'USER32::MapWindowPoints(i0,i$hwndparent,ir1,i2)'
System::Call '*(i.r4,i.r5,i.r6,i.r7)'
System::Free
IntOp -
IntOp -
System::Call 'USER32::CreateWindowEx(i0, t "Static", i0, i${WS_CHILD}|${WS_VISIBLE}|${SS_OWNERDRAW}, ir4, ir5, ir6, ir7, i$hwndparent, i0, i0, i0)i.r0'
StrCpy $hStaticCtrl [=10=]
${WndSubclass_Subclass} $HWNDPARENT MainWndSubProc $MainWndSubProc $MainWndSubProc
FunctionEnd
Section
SectionEnd
你的 C 代码质量让我相信你还没有准备好编写这种代码。如果您查看 DRAWITEMSTRUCT 的文档,您会看到 hDC 成员的评论:"this device context must be used when performing drawing operations on the control." 但您决定调用 BeginPaint
!您也无法恢复 DC,并且删除了选择到 DC 中但不允许的对象。