#Persistent
#Singleinstance force
#Include ControlCol.ahk
Gui Destroy
Gui, Add, Text, hwndh_1, Text1
Gui, Add, Edit, hwndh_2, Edit
Gui, Add, Edit, hwndh_3, Edit
Gui, Add, UpDown, hwndh_4, UpDown
Gui, Add, Picture, hwndh_5, Picture
Gui, Add, Button, hwndh_6, Button
Gui, Add, CheckBox, hwndh_7, CheckBox
Gui, Add, Radio, hwndh_8, Radio
Gui, Add, ListBox, hwndh_9, ListBox
Gui, Add, Link, hwndh_10, Link
Gui, Add, Edit, w320 h50 HwndMyTextHwnd, Here is some text that is given`na custom background color.
Gui, Add, Edit, w320 h50 HwndMyTextHwnd2, Here is some text that is given`na custom background color.
Gui, Add, Edit, w320 h50 HwndMyTextHwnd3, Here is some text that is given`na custom background color.
Gui +LastFound
GuiHwnd := WinExist()
;MsgBox, % GuiHwnd
Gui Show
loop
{
Sleep, 50
Random, t, 0, 0xffffff
Random, b, 0, 0xffffff
;MsgBox, %t%, %b%
t := "0x" SubStr(Format("{:p}", t), 3)
b := "0x" SubStr(Format("{:p}", b), 3)
loop, 10 {
ControlCol(H_%A_Index%, GuiHwnd, b, t)
}
GuiControl, text, Edit5, %A_Index%
}
ControlCol(h_1, hMainWnd, 0x9FCFFF, 0xffffff)
ControlCol(MyTextHwnd2, hMainWnd, 0x00ff00, 0x0000ff)
ControlCol(MyTextHwnd3, hMainWnd, 0x0000ff, 0xff0000)
count := 0
;SetTimer, c, 500
return
c:
Random, b, 0, 0xffffff
Random, t, 0, 0xffffff
ControlCol(MyTextHwnd,GuiHwnd, b, t)
ControlCol(MyTextHwnd2,GuiHwnd, b, t)
abc := ControlCol(MyTextHwnd3,GuiHwnd, b, t)
count ++
GuiControl, text, Edit5, %Count% %abc%
return
f4::
ExitApp
return
GuiClose:
ExitApp
ControlCol.ahk
; ------------------------
; http://www.autohotkey.com/board/topic/104539-controlcol-set-background-and-text-color-gui-controls/
; v1.0.2
; ------------------------
ControlCol(Control, Window, bc="", tc="", redraw=1) {
; msgbox
a := []
a["c"] := Control
a["g"] := Window
a["bc"] := (bc="")?"":(((bc&255)<<16)+(((bc>>8)&255)<<8)+(bc>>16))
a["tc"] := (tc="")?"":((tc&255)<<16)+(((tc>>8)&255)<<8)+(tc>>16)
WindowProc("Set", a, "", "")
If redraw
{
SizeOfWINDOWINFO := 10
VarSetCapacity(WINDOWINFO, SizeOfWINDOWINFO, 0)
NumPut(SizeOfWINDOWINFO, WINDOWINFO, "UInt")
DllCall("GetWindowInfo", "Ptr", Control, "Ptr", &WINDOWINFO)
;FileAppend, GetWindowInfo %ErrorLevel%`n, %A_ScriptDir%\ControlCol.log
DllCall("ScreenToClient", "Ptr", Window, "Ptr", &WINDOWINFO+20) ; x1,y1 of Client area
;FileAppend, ScreenToClient %ErrorLevel%`n, %A_ScriptDir%\ControlCol.log
DllCall("ScreenToClient", "Ptr", Window, "Ptr", &WINDOWINFO+28) ; x2,y2 of Client area
;FileAppend, ScreenToClient %ErrorLevel%`n, %A_ScriptDir%\ControlCol.log
DllCall("RedrawWindow"
, "Ptr", Window ; A handle to the window to be redrawn. If this parameter is NULL, the desktop window is updated.
, "UInt", &WINDOWINFO+20 ; A pointer to a RECT structure containing the coordinates, in device units, of the update rectangle. This parameter is ignored if the hrgnUpdate parameter identifies a region.
, "UInt", 0 ; A handle to the update region. If both the hrgnUpdate and lprcUpdate parameters are NULL, the entire client area is added to the update region.
, "UInt", 0x101) ; One or more redraw flags. This parameter can be used to invalidate or validate a window, control repainting, and control which windows are affected by RedrawWindow.
;FileAppend, RedrawWindow %ErrorLevel%`n, %A_ScriptDir%\ControlCol.log
VarSetCapacity(WINDOWINFO, 0)
}
return
}
WindowProc(hwnd, uMsg, wParam, lParam)
{
Static Win := {}
;Critical
If uMsg between 0x132 and 0x138
If Win[hwnd].HasKey(lparam)
{
FileAppend, %A_Now% %A_MSec% %ErrorLevel%`n, %A_ScriptDir%\ControlCol.log
If tc := Win[hwnd, lparam, "tc"]
DllCall("SetTextColor", "UInt", wParam, "UInt", tc)
If bc := Win[hwnd, lparam, "bc"]
DllCall("SetBkColor", "UInt", wParam, "UInt", bc)
return Win[hwnd, lparam, "Brush"] ; Return the HBRUSH to notify the OS that we altered the HDC.
}
;}
If (hwnd = "Set")
{
;MsgBox, fsefs
a := uMsg
Win[a.g, a.c] := a
If (Win[a.g, a.c, "tc"] = "") and (Win[a.g, a.c, "bc"] = "")
Win[a.g].Remove(a.c, "")
If not Win[a.g, "WindowProcOld"]
Win[a.g,"WindowProcOld"] := DllCall("SetWindowLong", "Ptr", a.g, "Int", -4, "Int", RegisterCallback("WindowProc", "", 4), "UInt")
If Win[a.g, a.c, "Brush"]
DllCall("DeleteObject", "Ptr", Brush)
If (Win[a.g, a.c, "bc"] != "")
Win[a.g, a.c, "Brush"] := DllCall("CreateSolidBrush", "UInt", a.bc)
; array_list(a)
return
}
q1234 := DllCall("CallWindowProcA", "UInt", Win[hwnd, "WindowProcOld"], "UInt", hwnd, "UInt", uMsg, "UInt", wParam, "UInt", lParam)
return q1234
}
http://www.autohotkey.com/board/topic/104539-controlcol-set-background-and-text-color-gui-controls/
这种情况是由于你的脚本运行次数太多导致的。在修改同一个控件或多个控件多次后窗口崩溃是因为 GDI 对象泄露。GDI 对象是 Windows 使用的图形对象,当你创建太多的 GDI 对象而不释放它们,就会导致 GDI 对象泄露。
解决方法是使用 gdi32.dll 的 DeleteObject 函数来释放创建的 GDI 对象。可以在 ControlCol.ahk 中添加一个函数来删除之前创建的 GDI 对象:
ControlCol.ahk:
; ------------------------
; http://www.autohotkey.com/board/topic/104539-controlcol-set-background-and-text-color-gui-controls/
; v1.0.2
; ------------------------
ControlCol(Control, Window, bc="", tc="", redraw=1) {
static hBrush
; ...
if (hBrush)
DllCall("gdi32.dll\DeleteObject", "ptr", hBrush)
; ...
}
这样,在每次调用 ControlCol 函数时都会释放上一次创建的 GDI 对象,避免 GDI 对象泄露。
您好,根据您描述的问题,在修改GUI控件Background 颜色窗口时,发生多次修改后窗口奔溃的现象。从您提供的信息来分析,不排除是楼上所说的GDI资源泄露问题,这个问题一般都是发生在对主程序刷新界面,导致主程序重绘,消耗GDI资源。
解决方法是:
1、在每次修改GUI控件Background 颜色后观察GDI资源使用量,操作方法以win10系统的电脑为例:
1)打开任务管理器,选择详细信息
2)在名称的那行标题栏上右键
3)在弹出的窗口中,选择GDI对象那一列
4)然后你回到任务管理器中,就可以观察到GDI资源使用量
2、当你确定多次修改GUI控件Background 颜色后,GDI资源使用量太大后,比如达到几千,那么基本就确定是这个问题了
3、那您就需要检查或调试您的代码,看下是否调用相关对象后没有及时释放掉
4、如果您不知道怎么定位哪里的代码导致的泄露问题,可以下载一些第三方软件来帮助您,比如GDI泄露的工具GDILeaks