forked from camerb/AHKs
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Win.ahk
802 lines (667 loc) · 29.7 KB
/
Win.ahk
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
/*
Title: Win
Set of window functions.
*/
/*
Function: Animate
Enables you to produce special effects when showing or hiding windows.
Parameters:
Type - White space separated list of animation flags. By default, these flags take effect when showing a window.
Time - Specifies how long it takes to play the animation, in millisecond .
Animation types:
activate - Activates the window. Do not use this value with HIDE flag.
blend - Uses a fade effect. This flag can be used only if hwnd is a top-level window.
center - Makes the window appear to collapse inward if HIDE is used or expand outward if the HIDE is not used. The various direction flags have no effect.
hide - Hides the window. By default, the window is shown.
slide - Uses slide animation. Ignored when used with CENTER.
:
hneg - Animates the window from right to left. This flag can be used with roll or slide animation. It is ignored when used with CENTER or BLEND.
hpos - Animates the window from left to right. This flag can be used with roll or slide animation. It is ignored when used with CENTER or BLEND.
vneg - Animates the window from top to bottom. This flag can be used with roll or slide animation. It is ignored when used with CENTER or BLEND.
vpos - Animates the window from bottom to top. This flag can be used with roll or slide animation. It is ignored when used with CENTER or BLEND.
Remarks:
When using slide or roll animation, you must specify the direction.
You can combine HPOS or HNEG with VPOS or VNEG to animate a window diagonally.
If a child window is displayed partially clipped, when it is animated it will have holes where it is clipped.
Avoid animating a window that has a drop shadow because it produces visually distracting, jerky animations.
Returns:
If the function succeeds, the return value is nonzero.
Example:
> Win_Animate(hWnd, "hide blend", 500)
*/
Win_Animate(Hwnd, Type="", Time=100){
static AW_ACTIVATE = 0x20000, AW_BLEND=0x80000, AW_CENTER=0x10, AW_HIDE=0x10000
,AW_HNEG=0x2, AW_HPOS=0x1, AW_SLIDE=0x40000, AW_VNEG=0x8, AW_VPOS=0x4
hFlags := 0
loop, parse, Type, %A_Tab%%A_Space%, %A_Tab%%A_Space%
ifEqual, A_LoopField,,continue
else hFlags |= AW_%A_LoopField%
ifEqual, hFlags, ,return "Err: Some of the types are invalid"
DllCall("AnimateWindow", "uint", Hwnd, "uint", Time, "uint", hFlags)
}
/*
Function: FromPoint
Retrieves a handle to the top level window that contains the specified point.
Parameters:
X, Y - Point. Use word "mouse" as X to use mouse coordinates.
*/
Win_FromPoint(X="mouse", Y="") {
if X=mouse
VarSetCapacity(POINT, 8), DllCall("GetCursorPos", "uint", &POINT), X := NumGet(POINT), Y := NumGet(POINT, 4)
VarSetCapacity(POINT, 8), NumPut(X, POINT, 0, "Int"), NumPut(Y, POINT, 4, "Int")
return DllCall("WindowFromPoint", &POINT)
}
/*
Function: Get
Get window information.
Parameters:
pQ - List of query parameters.
o1 .. o9 - Reference to output variables. R,L,B & N query parameters can return multiple outputs.
Query:
C,I - Class, pId.
R,L,B,N - One of the window rectangles: R (window Rectangle), L (cLient rectangle screen coordinates), B (ver/hor Border), N (captioN rect).
N returns the size of the caption regardless of the window style or theme. These coordinates include all title-bar elements except the window menu.
The function returns x, y, w & h separated by space.
For all 4 query parameters you can additionaly specify x,y,w,h arguments in any order (except Border which can have only x(hor) and y(ver) arguments) to
extract desired number into output variable.
S,E - Style, Extended style.
P,A,O - Parents handle, Ancestors handle, Owners handle.
M - Module full path (owner exe), unlike WinGet,,ProcessName which returns only name without path.
T - Title for a top level window or text for a child window.
D - DC.
# - Non-negative integer. If present must be first option in the query string. Function will return window information
not for passed window but for its ancestor. 1 is imidiate parent, 2 is parent's parent etc... 0 represents root window.
Returns:
o1
Examples:
(start code)
Win_Get(hwnd, "CIT", class, pid, text) ;get class, pid and text
Win_Get(hwnd, "RxwTC", x, w, t, c) ;get x & width attributes of window rect, title and class
Win_Get(hwnd, "RxywhCLxyTBy",wx,wy,ww,wh,c,lx,ly,t,b) ;get all 4 attributes of window rect, class, x & y of client rect, text and horizontal border height
right := Win_Get(hwnd, "Rx") + Win_Get(hwnd, "Rw") ;first output is returned as function result so u can use function in expressions.
Win_Get(hwnd, "Rxw", x, w), right := x+w ;the same as above but faster.
right := Win_Get(hwnd, "Rxw", x, w ) + w ;not recommended.
Win_Get(hwnd, "1CIT", class, pid, text) ;get class, pid and text for parent of the hwnd.
rect := Win_Get(hwnd, "0R") ;get rectangle of the root window.
(end code)
*/
Win_Get(Hwnd, pQ="", ByRef o1="", ByRef o2="", ByRef o3="", ByRef o4="", ByRef o5="", ByRef o6="", ByRef o7="", ByRef o8="", ByRef o9="") {
c := SubStr(pQ, 1, 1)
if c is integer
{
if (c = 0)
Hwnd := DllCall("GetAncestor", "uint", Hwnd, "uint", 2, "UInt")
else loop, %c%
Hwnd := DllCall("GetParent", "uint", Hwnd, "UInt")
pQ := SubStr(pQ, 2)
}
if pQ contains R,B,L
VarSetCapacity(WI, 60, 0), NumPut(60, WI), DllCall("GetWindowInfo", "uint", Hwnd, "uint", &WI)
oldDetect := A_DetectHiddenWindows
DetectHiddenWindows, on
k := i := 0
loop
{
i++, k++
if (_ := SubStr(pQ, k, 1)) = ""
break
if !IsLabel("Win_Get_" _ )
return A_ThisFunc "> Invalid query parameter: " _
Goto %A_ThisFunc%_%_%
Win_Get_C:
WinGetClass, o%i%, ahk_id %hwnd%
continue
Win_Get_I:
WinGet, o%i%, PID, ahk_id %hwnd%
continue
Win_Get_N:
rect := "title"
VarSetCapacity(TBI, 44, 0), NumPut(44, TBI, 0), DllCall("GetTitleBarInfo", "uint", Hwnd, "str", TBI)
title_x := NumGet(TBI, 4, "Int"), title_y := NumGet(TBI, 8, "Int"), title_w := NumGet(TBI, 12) - title_x, title_h := NumGet(TBI, 16) - title_y
WinGet, style, style, ahk_id %Hwnd%
title_h := style & 0xC00000 ? title_h : 0 ; if no WS_CAPTION style, set 0 as win sets randoms otherwise...
goto Win_Get_Rect
Win_Get_B:
rect := "border"
border_x := NumGet(WI, 48, "UInt"), border_y := NumGet(WI, 52, "UInt")
goto Win_Get_Rect
Win_Get_R:
rect := "window"
window_x := NumGet(WI, 4, "Int"), window_y := NumGet(WI, 8, "Int"), window_w := NumGet(WI, 12, "Int") - window_x, window_h := NumGet(WI, 16, "Int") - window_y
goto Win_Get_Rect
Win_Get_L:
client_x := NumGet(WI, 20, "Int"), client_y := NumGet(WI, 24, "Int"), client_w := NumGet(WI, 28, "Int") - client_x, client_h := NumGet(WI, 32, "Int") - client_y
rect := "client"
Win_Get_Rect:
k++, arg := SubStr(pQ, k, 1)
if arg in x,y,w,h
{
o%i% := %rect%_%arg%, j := i++
goto Win_Get_Rect
}
else if !j
o%i% := %rect%_x " " %rect%_y (_ = "B" ? "" : " " %rect%_w " " %rect%_h)
rect := "", k--, i--, j := 0
continue
Win_Get_S:
WinGet, o%i%, Style, ahk_id %Hwnd%
continue
Win_Get_E:
WinGet, o%i%, ExStyle, ahk_id %Hwnd%
continue
Win_Get_P:
o%i% := DllCall("GetParent", "uint", Hwnd, "UInt")
continue
Win_Get_A:
o%i% := DllCall("GetAncestor", "uint", Hwnd, "uint", 2, "UInt") ; GA_ROOT
continue
Win_Get_O:
o%i% := DllCall("GetWindowLong", "uint", Hwnd, "int", -8, "UInt") ; GWL_HWNDPARENT
continue
Win_Get_T:
if DllCall("IsChild", "uint", Hwnd)
WinGetText, o%i%, ahk_id %hwnd%
else WinGetTitle, o%i%, ahk_id %hwnd%
continue
Win_Get_M:
WinGet, _, PID, ahk_id %hwnd%
hp := DllCall( "OpenProcess", "uint", 0x10|0x400, "int", false, "uint", _ )
if (ErrorLevel or !hp)
continue
VarSetCapacity(buf, 512, 0), DllCall( "psapi.dll\GetModuleFileNameExA", "uint", hp, "uint", 0, "str", buf, "uint", 512), DllCall( "CloseHandle", hp )
o%i% := buf
continue
Win_Get_D:
o%i% := DllCall("GetDC", "uint", Hwnd, "UInt")
continue
}
DetectHiddenWindows, %oldDetect%
return o1
}
/*
Function: GetRect
Get window rectangle.
Parameters:
hwnd - Window handle
pQ - Query parameter: ordered list of x, y, w and h characters and optionally type specified as first charachter.
Use * to get placement relative to the client area of the parent's window, or ! get placement relative to the root window.
Omit x,y,w,h to return all attributes separated by space for given placement type.
o1 .. o4 - Reference to output variables.
Returns:
o1 or string with all coordinates.
Remarks:
This function is faster alternative to <Get> with R parameter. However, if you query additional window info using <Get>, it may be faster and definitely more
convenient then obtaining the info using alternatives.
Besides that, you can't use <Get> to obtain relative coordinates of child windows.
Examples:
(start code)
Win_GetRect(hwnd, "xw", x, w) ;get x & width
Win_GetRect(hwnd, "yhx", y, h, x) ;get y, height, and x
p := Win_GetRect(hwnd, "x") + 5 ;for single query parameter you don't need output variable as function returns o1
all := Win_GetRect(hwnd) ;return all
Win_Get(hwnd, "*hx", h, x) ;return relative h and x
all_rel := WiN_Get(hwnd, "*") ;return all, relative coordinates
(end code)
*/
Win_GetRect(hwnd, pQ="", ByRef o1="", ByRef o2="", ByRef o3="", ByRef o4="") {
VarSetCapacity(RECT, 16), r := DllCall("GetWindowRect", "uint", hwnd, "uint", &RECT)
ifEqual, r, 0, return
if (pQ = "") or pQ = ("*")
retAll := true, pQ .= "xywh"
xx := NumGet(RECT, 0, "Int"), yy := NumGet(RECT, 4, "Int"), c := SubStr(pQ, 1, 1)
if (c = "*")
Win_Get(DllCall("GetParent", "uint", hwnd), "Lxy", lx, ly), xx -= lx, yy -= ly, pQ := SubStr(pQ, 2)
else if (c = "!")
Win_Get(DllCall("GetAncestor", "uint", Hwnd, "uint", 2), "Lxy", lx, ly), xx -= lx, yy -= ly, pQ := SubStr(pQ, 2)
loop, parse, pQ
if A_LoopField = x
o%A_Index% := xx
else if A_LoopField = y
o%A_Index% := yy
else if A_LoopField = w
o%A_Index% := NumGet(RECT, 8, "Int") - xx - ( lx ? lx : 0)
else if A_LoopField = h
o%A_Index% := NumGet(RECT, 12, "Int") - yy - ( ly ? ly : 0 )
return retAll ? o1 " " o2 " " o3 " " o4 : o1
}
/*
Function: GetChildren
Get first level child windows for a window.
Parameters:
Hwnd - Handle of the parent window.
Returns:
New line separated list of child control handles.
*/
Win_GetChildren(Hwnd){
static GW_HWNDNEXT=2, GW_CHILD=5, adrGetWindow
if !adrGetWindow
adrGetWindow := DllCall("GetProcAddress", "uint", DllCall("GetModuleHandle", "str", "user32"), "str", "GetWindow")
s := hChild := DllCall(adrGetWindow, "uint", Hwnd, "uint", GW_CHILD)
ifEqual, s,0, return
while (hChild := DllCall(adrGetWindow, "uint", hChild, "uint", GW_HWNDNEXT))
s .= "`n" hChild
return s
}
/*
Function: GetClassNN
Get a control ClassNN.
Parameters:
HCtrl - Handle of the parent window.
HRoot - Handle of the top level window containing control.
Returns:
ClassNN
About:
o Developed by Lexikos. See <http://www.autohotkey.com/forum/viewtopic.php?p=308628#308628>
*/
Win_GetClassNN(HCtrl, HRoot="") {
ifEqual, HRoot,, SetEnv, HRoot, % DllCall("GetAncestor", "uint", HCtrl, "Uint", 2, "Uint")
WinGet, hlist, ControlListHwnd, ahk_id %HRoot%
WinGetClass, tclass, ahk_id %HCtrl%
Loop, Parse, hlist, `n
{
WinGetClass, lclass, ahk_id %A_LoopField%
if (lclass == tclass)
{
nn += 1
if A_LoopField = %hctl%
return tclass nn
}
}
}
/*
Function: Is
Checks handle against specified criterium.
Parameters:
pQ - Query parameter.
Query:
win - True if handle is window.
child - True if handle is child window.
enabled - True if window is enabled.
visible - True if window is visible.
max - True if window is maximized.
hung - True if window is hung and doesn't respond to messages.
Returns:
TRUE or FALSE
*/
Win_Is(Hwnd, pQ="win") {
static is_win = "IsWindow", is_child="IsChild", is_enabled="IsWindowEnabled", is_visible="IsWindowVisible", is_max = "IsZoomed", is_hung = "IsHungAppWindow"
fun := "is_" pQ, fun := %fun%
ifEqual, fun, , return A_ThisFunc "> Invalid query parameter: " pQ
return DllCall(fun, "uint", Hwnd)
}
/*
Function: Move
Change the size and position of a child, pop-up, or top-level window.
Parameters:
X..H - Size / position. You can omit any parameter to keep its current value.
Flags - Can be R or A.
Flags:
R - Does not redraw changes. If this flag is set, no repainting of any kind occurs.
A - Asynchronous mode - if the calling thread and the thread that owns the window are attached to different input queues, the system posts the request to the thread that owns the window. This prevents the calling thread from blocking its execution while other threads process the request.
Returns:
True if successful, False otherwise.
Remarks:
Does not produce the same effect as ControlMove on child windows. Mentioned AHK function puts child window relative to the ancestor window rectangle
while Win_Move puts it relative to the parent's client rectangle which is usually the wanted behavior.
WinMove produces the same effect as Win_Move on child controls, except its X and Y parameters are not optional which makes lot of additional code for frequent operation: moving the control by some offset of its current position.
In order to do that you must get the current position of the control. That can be done with ControlGetPos which works in pair with ControlMove hence it is not relative to the client rect or WinGetPos which returns screen coordinates of child control so those can not
be immediately used in WinMove as it positions child window relative to the parents client rect. This scenario can be additionally complicated by the fact that each window may have its own theme which influences the size of its borders, non client area, etc...
*/
Win_Move(Hwnd, X="", Y="", W="", H="", Flags="") {
; static SWP_NOMOVE=2, SWP_NOREDRAW=8, SWP_NOSIZE=1, SWP_NOZORDER=4, SWP_NOACTIVATE = 0x10, SWP_ASYNCWINDOWPOS=0x4000, HWND_BOTTOM=1, HWND_TOPMOST=-1, HWND_NOTOPMOST = -2
static SWP_NOMOVE=2, SWP_NOSIZE=1, SWP_NOZORDER=4, SWP_NOACTIVATE=16, SWP_R=8, SWP_A=0x4000
hFlags := SWP_NOZORDER | SWP_NOACTIVATE
loop, parse, Flags
hFlags |= SWP_%A_LoopField%
if (X Y != "") {
p := DllCall("GetParent", "uint", Hwnd), Win_Get(p, "Lxy", px, py), Win_GetRect(Hwnd, "xywh", cx, cy, cw, ch)
ifEqual, X,, SetEnv, X, % cx - px
ifEqual, Y,, SetEnv, Y, % cy - py
} else hFlags |= SWP_NOMOVE
if (W H != "") {
if !cx
Win_GetRect(Hwnd, "wh", cw, ch)
ifEqual, W,, SetEnv, W, %cw%
ifEqual, H,, SetEnv, H, %ch%
} else hFlags |= SWP_NOSIZE
return DllCall("SetWindowPos", "uint", Hwnd, "uint", 0, "int", X, "int", Y, "int", W, "int", H, "uint", hFlags)
}
/*
Function: MoveDelta
Move the window by specified amount.
Parameters:
Xd .. Hd - Delta to add to each window rect property. Skipped properties will not be changed.
Flags - The same as in <Move>.
Returns:
True if successful, False otherwise.
*/
Win_MoveDelta( Hwnd, Xd="", Yd="", Wd="", Hd="", Flags="" ) {
Win_GetRect(Hwnd, "*xywh", cx, cy, cw, ch)
return Win_Move( Hwnd, cx+Xd, cy+Yd, cw+Wd, ch+Hd, flags)
}
/*
Function: Recall
Store & recall window position, size and/or state.
Parameters:
Options - White space separated list of options. See bellow.
Hwnd - Hwnd of the window for which to store data or Gui number if AHK window.
If omitted, function will use Hwnd of the default AHK Gui. You can also use Gui, N:Default
prior to calling the function. For 3td party windows, this parameter is mandatory.
Set 0 as hwnd to return position string without applying it to any window. This can be used for AHK Guis to
calculate size of controls based on window size and position, when needed.
IniFileName - Ini file to use as storage. Function will save the data under the [Recall] section.
If omitted, Windows Registry key HKEY_CURRENT_USER\AutoHotKey\Win is used. Each script is uniquely determined by its full path
so same scripts with different name will not share the storage.
Options:
">", "<", "-", "--" - Operation, mandatory option. Use ">" to store or "<" to recall window position.
It can be optionally followed by the string representing the name of the storage location for that window.
You need to use name if your script stores more then one window, otherwise it will be saved under unnamed location.
">" and "<" are special names that can be used to store or recall all AHK Guis.
"-" operation is used alone as an argument to delete Registry or Ini sections belonging to the script.
"--" operation is used alone as an argument to delete all Registry entries for all scripts.
-Min - Don't save minimize state.
-Max - Don't save maximized state.
Returns:
Position string, space separated list of syntax "left top right bottom state cw ch" of the window.
Empty if no recall data is stored for the window.
State can be 1 (normal) 2 (minimized) or 3 (maximized).
cw & ch numbers are present only for AHK Guis and represent client width & height which can be used
without modifications in Gui, Show command.
Examples:
Single Gui Example:
(start code)
Gui, +Resize +LastFound
WinSetTitle, MyGui
if !Win_Recall("<") ;Recall gui if its position is already saved
Gui, Show, h300 w300, MyGui ; otherwise use these defaults.
return
GuiClose:
Win_Recall(">") ;Store the Gui.
ExitApp
return
(end code)
Snippets:
(start code)
Win_Recall(">MyGui") ;Save position for default Gui under name MyGui.
Win_Recall("<MyGui") ;Recall position for MyGui for default Gui
Win_Recall(">MyGui2", Hwnd) ;Save window position under MyGui2 name, given the window handle or Gui number.
Win_Recall(">>") ;Save all Guis. The names will be given by their number.
Win_Recall("<<") ;Recall all Guis.
Win_Recall("-") ;Delete all Registry entries for the script.
Win_Recall("--") ;Delete all Registry entries for all scripts.
pos := Win_Recall("<MyWin", 0) ;Return position string only for window saved under the "MyWin" name.
(end code)
*/
Win_Recall(Options, Hwnd="", IniFileName=""){
static key="Software\AutoHotkey\Win", section="Recall"
if (Options = "-"){
ifNotEqual, IniFileName,, IniDelete, %IniFileName%, %section%
else loop, HKEY_CURRENT_USER, %key%
InStr(A_LoopRegName, A_ScriptFullPath) ?
RegDelete, HKEY_CURRENT_USER, %key%, %A_LoopRegName%
return
} else if (Options = "--") {
RegDelete, HKEY_CURRENT_USER, %key%
return
}
loop, parse, Options, %A_Space%%A_Tab%, %A_Space%%A_Tab%
{
ifEqual, A_LoopField, ,continue
f := SubStr(A_LoopField, 1, 1), p := SubStr(A_LoopField, 2)
ifEqual, f, >, SetEnv, op, % ">", name := p
else ifEqual, f, <, SetEnv, op, % "<", name := p
else ifEqual, A_LoopField, -Min, SetEnv, noMin, 1
else ifEqual, A_LoopField, -Max, SetEnv, noMax, 1
}
if (Hwnd = "") || (Hwnd>0 && Hwnd <= 99) {
ifEqual, Hwnd,, Gui, +LastFoundExist
else Gui, %Hwnd%:+LastFound
Hwnd := WinExist()
}
if name in <,>
{
Loop, 99 {
Gui, %A_Index%:+LastFoundExist
if WinExist() {
name := A_Index, Hwnd := WinExist()
gosub %A_ThisFunc%
}
}
return
}
Win_Recall:
if (op = "<") {
if IniFileName !=
IniRead, pos, %IniFileName%, %section%, !%name%, %A_Space%
else RegRead, pos, REG_SZ, HKEY_CURRENT_USER, %key%, %A_ScriptFullPath%!%name%
if (pos = "") or !Hwnd
return pos
VarSetCapacity(WP, 44, 0), NumPut(44,WP)
StringSplit p, pos, %A_Space%
p5 := (p5=2 && noMin) || (p5=3 && noMax) ? 1 : p5
loop, 4
NumPut(p%A_Index%, WP, (A_Index+6)*4, "Int")
NumPut(p5, WP, 8, "UInt")
DllCall("SetWindowPlacement", "uint", Hwnd, "uint", &WP)
}
else if (op = ">"){
VarSetCapacity(WP, 44, 0), NumPut(44,WP)
DllCall("GetWindowPlacement", "uint", Hwnd, "uint", &WP)
WinGetClass, cls, ahk_id %hwnd%
if (cls="AutoHotkeyGUI")
Win_Get(Hwnd, "Lwh",w,h), szAHK := " " w " " h ;Store AHK client width & height so it can be used with Gui, Show.
pos := ""
loop, 4
pos .= NumGet(WP, (A_Index+6)*4, "Int") " "
s := NumGet(WP, 8, "UInt")
pos .= (s != 0 ? s : 1) szAHK
if IniFileName !=
IniWrite, %pos%, %IniFileName%, %section%, !%name%
else RegWrite, REG_SZ, HKEY_CURRENT_USER, %key%, %A_ScriptFullPath%!%name%, %pos%
}
return pos
}
/*
Function: Redraw
Redraws the window.
Parameters:
Hwnd - Handle of the window. If this parameter is omitted, Redraw updates the desktop window.
Option - "-" to disable redrawing for the window. "+" to enable it and redraw it. By default empty.
Returns:
A nonzero value indicates success. Zero indicates failure.
Remarks:
This function will update the window for sure, unlike WinSet or InvalidateRect.
*/
Win_Redraw( Hwnd=0, Option="" ) {
static WM_SETREDRAW=0xB, RDW_ALLCHILDREN:=0x80, RDW_ERASE:=0x4, RDW_ERASENOW:=0x200, RDW_FRAME:=0x400, RDW_INTERNALPAINT:=0x2, RDW_INVALIDATE:=0x1, RDW_NOCHILDREN:=0x40, RDW_NOERASE:=0x20, RDW_NOFRAME:=0x800, RDW_NOINTERNALPAINT:=0x10, RDW_UPDATENOW:=0x100, RDW_VALIDATE:=0x8
if (Option != "") {
old := A_DetectHiddenWindows
DetectHiddenWindows, on
bEnable := Option="+"
SendMessage, 0xB, bEnable,,,ahk_id %Hwnd%
DetectHiddenWindows, %old%
ifEqual, bEnable, 0, return
}
return DllCall("RedrawWindow", "uint", Hwnd, "uint", 0, "uint", 0, "uint" ,RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_ERASENOW | RDW_UPDATENOW | RDW_ALLCHILDREN)
}
/*
Function: SetCaption
Set visibility of the window caption.
Parameters:
Flag - Set + to show the caption or - otherwise. If omitted, caption will be toggled.
*/
Win_SetCaption(Hwnd, Flag="^"){
oldDetect := A_DetectHiddenWindows
DetectHiddenWindows, on
WinSet, Style, %Flag%0xC00000
DetectHiddenWindows, %oldDetect%
}
/*
Function: SetMenu
Set the window menu.
Parameters:
hMenu - Handle of the menu to set for window. By default 0 means that menu will be removed.
Returns:
Handle of the previous menu.
*/
Win_SetMenu(Hwnd, hMenu=0){
hPrevMenu := DllCall("GetMenu", "uint", hwnd, "Uint")
DllCall("SetMenu", "uint", hwnd, "uint", hMenu)
return hPrevMenu
}
/*
Function: SetIcon
Set the titlebar icon for the window.
Parameters:
Icon - Path to the icon. If omitted, icon is removed. If integer, handle to the already loaded icon.
Flag - 1 sets the large icon for the window, 0 sets the small icon for the window.
Returns:
The return value is a handle to the previous large or small icon, depending on the Flag value.
*/
Win_SetIcon(Hwnd, Icon="", Flag=1){
static WM_SETICON = 0x80, LR_LOADFROMFILE=0x10, IMAGE_ICON=1
if Flag not in 0,1
return A_ThisFunc "> Unsupported Flag: " Flag
if Icon !=
hIcon := Icon+0 != "" ? Icon : DllCall("LoadImage", "Uint", 0, "str", Icon, "uint",IMAGE_ICON, "int", 32, "int", 32, "uint", LR_LOADFROMFILE)
SendMessage, WM_SETICON, %Flag%, hIcon, , ahk_id %Hwnd%
return ErrorLevel
}
/*
Function: SetParent
Changes the parent window of the specified window.
Parameters:
Hwnd - Handle of the window for which to send parent.
HParent - Handle to the parent window. If this parameter is 0, the desktop window becomes the new parent window.
bFixStyle - Set to TRUE to fix WS_CHILD & WS_POPUP styles. SetParent does not modify the WS_CHILD or WS_POPUP window styles of the window whose parent is being changed.
If HParent is 0, you should also clear the WS_CHILD bit and set the WS_POPUP style after calling SetParent (and vice-versa).
Returns:
If the function succeeds, the return value is a handle to the previous parent window. Otherwise, its 0.
Remarks:
If the window identified by the Hwnd parameter is visible, the system performs the appropriate redrawing and repainting.
The function sends WM_CHANGEUISTATE to the parent after succesifull operation uncoditionally.
See <http://msdn.microsoft.com/en-us/library/ms633541(VS.85).aspx> for more information.
*/
Win_SetParent(Hwnd, HParent=0, bFixStyle=false){
static WS_POPUP=0x80000000, WS_CHILD=0x40000000, WM_CHANGEUISTATE=0x127, UIS_INITIALIZE=3
if (bFixStyle) {
s1 := Hwnd ? "+" : "-", s2 := Hwnd ? "-" : "+"
WinSet, Style, %s1%%WS_CHILD%, ahk_id %Hwnd%
WinSet, Style, %s2%%WS_POPUP%, ahk_id %Hwnd%
}
r := DllCall("SetParent", "uint", Hwnd, "uint", HParent)
ifEqual, r, 0, return 0
SendMessage, WM_CHANGEUISTATE, UIS_INITIALIZE,,,ahk_id %HParent%
return r
}
/*
Function: SetOwner
Changes the owner window of the specified window.
Parameters:
hOwner - Handle to the owner window.
Returns:
Handle of the previous owner.
Remarks:
An owned window is always above its owner in the z-order. The system automatically destroys an owned window when its owner is destroyed. An owned window is hidden when its owner is minimized.
Only an overlapped or pop-up window can be an owner window; a child window cannot be an owner window.
*/
;Famous misleading statement. Almost as misleading as the choice of GWL_HWNDPARENT as the name. It has nothing to do with a window's parent.
;It really changes the Owner exactly the same thing as including the Owner argument in the Show statement.
;A more accurate version might be: "SetWindowLong with the GWL_HWNDPARENT will not change the parent of a child window. Instead, use the SetParent function."
;GWL_HWNDPARENT should have been called GWL_HWNDOWNER, but nobody noticed it until after a bazillion copies of the SDK had gone out. This is what happens
;when the the dev team lives on M&Ms and CocaCola for to long. Too bad. Live with it.
;
Win_SetOwner(Hwnd, hOwner){
static GWL_HWNDPARENT = -8
return DllCall("SetWindowLong", "uint", Hwnd, "int", GWL_HWNDPARENT, "uint", hOwner)
}
/*
Function: SetToolWindow
Set the WS_EX_TOOLWINDOW style for the window.
Parameters:
Flag - Set + to show the caption or - otherwise. If omitted, caption will be toggled.
*/
Win_SetToolWindow(Hwnd, Flag="^") {
static WS_EX_TOOLWINDOW = 0x80
oldDetect := A_DetectHiddenWindows
DetectHiddenWindows, on
WinSet, ExStyle, %FLag%WS_EX_TOOLWINDOW, ahk_id %Hwnd%
DetectHiddenWindows, %oldDetect%
}
/*
Function: Show
Show / Hide window.
Parameters:
bShow - True to show (default), False to hide window.
Returns:
If the window was previously visible, the return value is nonzero.
If the window was previously hidden, the return value is zero.
*/
Win_Show(Hwnd, bShow=true) {
return DllCall("ShowWindow", "uint", Hwnd, "uint", bShow ? 5:0)
}
/*
Function: ShowSysMenu
Show system menu for a window (ALT + SPACE menu).
Parameters:
X, Y - Coordinates on which to show menu. Pass word "mouse" as X (default) to use mouse coordinates.
Returns:
True if menu has been shown, False otherwise.
*/
Win_ShowSysMenu(Hwnd, X="mouse", Y="") {
static WM_SYSCOMMAND = 0x112, TPM_RETURNCMD=0x100
oldDetect := A_DetectHiddenWindows
DetectHiddenWindows, on
Process, Exist
h := WinExist("ahk_pid " ErrorLevel)
DetectHiddenWindows, %oldDetect%
if X=mouse
VarSetCapacity(POINT, 8), DllCall("GetCursorPos", "uint", &POINT), X := NumGet(POINT), Y := NumGet(POINT, 4)
hSysMenu := DllCall("GetSystemMenu", "Uint", Hwnd, "int", False)
r := DllCall("TrackPopupMenu", "uint", hSysMenu, "uint", TPM_RETURNCMD, "int", X, "int", Y, "int", 0, "uint", h, "uint", 0)
ifEqual, r, 0, return
PostMessage, WM_SYSCOMMAND, r,,,ahk_id %Hwnd%
return 1
}
/*
Function: Subclass
Subclass window.
Parameters:
Hwnd - Handle to the window to be subclassed.
Fun - New window procedure. You can also pass function address here in order to subclass child window
with previously created window procedure.
Opt - Optional callback options for Fun, by default ""
$WndProc - Optional reference to the output variable that will receive address of the new window procedure.
Returns:
The address of the previous window procedure or 0 on error.
Remarks:
Works only for controls created in the autohotkey process.
Example:
(start code)
if !Win_SubClass(hwndList, "MyWindowProc")
MsgBox, Subclassing failed.
...
MyWindowProc(hwnd, uMsg, wParam, lParam){
if (uMsg = .....)
; my message handling here
return DllCall("CallWindowProcA", "UInt", A_EventInfo, "UInt", hwnd, "UInt", uMsg, "UInt", wParam, "UInt", lParam)
}
(end code)
*/
Win_Subclass(Hwnd, Fun, Opt="", ByRef $WndProc="") {
if Fun is not integer
{
oldProc := DllCall("GetWindowLong", "uint", Hwnd, "uint", -4)
ifEqual, oldProc, 0, return 0
$WndProc := RegisterCallback(Fun, Opt, 4, oldProc)
ifEqual, $WndProc, , return 0
}
else $WndProc := Fun
return DllCall("SetWindowLong", "UInt", Hwnd, "Int", -4, "Int", $WndProc, "UInt")
}
/*
Group: About
o v1.24 by majkinetor.
o Reference: <http://msdn.microsoft.com/en-us/library/ms632595(VS.85).aspx>
o Licensed under GNU GPL <http://creativecommons.org/licenses/GPL/2.0/>
/*