Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Pin Window
#1
Hi Gintaras,
I wrote a set of functions that would place a little button next to the minimize button in the Dlg frame of IE, MS Office, Adobe Reader windows so that I could toggle their Zorder to be TOPMOST or NOTOPMOST. For some reason, I can't get them to get the TOPMOST message. Any thoughts? Also any way to decrease the hit on the CPU usage?

This function identifies new windows of the correct type and then passes their hwnd to the PinDlg

Function NewWindowPinMonitor
Code:
Copy      Help
rep
,0.5
,str WinRegex = "(Internet Explorer)|(Microsoft (PowerPoint|Excel|Word))|(Adobe Reader)"
,ARRAY(int)+ arrintPrevHwnds.redim
,rep
,,2
,,ARRAY(int) arrintHwnds.redim
,,win(WinRegex "" "" 0x200|0x400 0 0 arrintHwnds)
,,if arrintHwnds.len>10; continue
,,ARRAY(int) i3.redim
,,ArrayNonInterSect_Int(arrintHwnds arrintPrevHwnds i3);;to identify new windows handles
,,if i3.len
,,,out F"i3.len = {i3.len}"
,,,for _i 0 i3.len
,,,,out i3[_i]
,,,,out _s.getwintext(i3[_i])
,,,,act i3[_i];err
,,,,mac "PinDlg" i3[_i]
,,arrintPrevHwnds = arrintHwnds  
,


Function PinDlg
Code:
Copy      Help
\Dialog_Editor
function# hDlg message wParam lParam
if(hDlg) goto messages
RECT- r_TargetHwnd_Prev
int- TargetHwnd = val(_command)
out _s.getwintext(TargetHwnd)
ARRAY(int) arrPreExistingPinDlgs
win("PinDlg" "#32770" "" 0 0 0 arrPreExistingPinDlgs)
for _i 0 arrPreExistingPinDlgs.len
,if(arrPreExistingPinDlgs[_i])
,,int PreExistingPinDlgOwnerHwnd = GetWindow(arrPreExistingPinDlgs[_i] GW_OWNER)
,,if TargetHwnd = PreExistingPinDlgOwnerHwnd
,,,ret
,,,



;BEGIN DIALOG
;0 "" 0x90000840 0x0 0 0 14 14 "PinDlg"
;3 Button 0x54031043 0x0 0 0 14 14 "Pin"
;END DIALOG
;DIALOG EDITOR: "" 0x2030605 "" "" "" ""

if(!ShowDialog("PinDlg" &PinDlg 0 TargetHwnd)) ret


ret
;messages
sel message
,case WM_INITDIALOG
,int PinIcon = GetIcon(":1295 $qm$\function.ico")
,SendMessage(id(3 hDlg) BM_SETIMAGE IMAGE_ICON PinIcon)
,,SetTimer hDlg 1 50 0
,case WM_TIMER
,,sel wParam    
,,,case 1
,,,,ifi-(TargetHwnd)
,,,,,clo hDlg;ret
,,,,RECT r_TargetHwnd; DpiGetWindowRect TargetHwnd &r_TargetHwnd
,,,,if r_TargetHwnd.top != r_TargetHwnd_Prev.top or r_TargetHwnd.left != r_TargetHwnd_Prev.left or r_TargetHwnd.right != r_TargetHwnd_Prev.right;; to limit this to just when a window has been moved/resized
,,,,,Acc accMinButton
,,,,,if findrx(_s.getwintext(TargetHwnd) "Internet Explorer$")>-1
,,,,,,accMinButton.Find(TargetHwnd "PUSHBUTTON" "Minimize" "class=IEFrame" 0x5);err clo hDlg;ret
,,,,,if findrx(_s.getwintext(TargetHwnd) "Microsoft ((Word)|(PowerPoint)|(Excel))$")>-1
,,,,,,accMinButton.Find(TargetHwnd "PUSHBUTTON" "Minimize" "class=NetUIHWND" 0x5);err clo hDlg;ret            
,,,,,if findrx(_s.getwintext(TargetHwnd) "Adobe Reader$")>-1
,,,,,,accMinButton.Find(TargetHwnd "PUSHBUTTON" "Minimize" "class=AcrobatSDIWindow" 0x5);err clo hDlg;ret
,,,,,if accMinButton.a
,,,,,,int x y cx cy
,,,,,,accMinButton.Location(x y cx cy)
,,,,,,siz cx cy id(3 hDlg)
,,,,,,siz cx cy hDlg
,,,,,,mov  x-cx-3 y hDlg
,,,,r_TargetHwnd_Prev.top = r_TargetHwnd.top
,,,,r_TargetHwnd_Prev.left =  r_TargetHwnd.left  
,,,,r_TargetHwnd_Prev.right =  r_TargetHwnd.right
,case WM_DESTROY
,case WM_COMMAND goto messages2
ret
;messages2
sel wParam
,case 3;
,,if(but(id(3 hDlg)))
,,,Zorder TargetHwnd HWND_TOPMOST    ;;not as reliable for some reason        
,,else
,,,Zorder TargetHwnd HWND_NOTOPMOST
ret 1

A function I wrote to help get new unique elements out of the array. I am sure there are better ways of doing this but....

Function ArrayNonInterSect_Int
Code:
Copy      Help
function ARRAY(int)&i1 ARRAY(int)&i2 [ARRAY(int)&i3] [ARRAY(int)&i4]

ARRAY(int) arrintNonIntersect_arr1 arrintNonIntersect_arr2
;Returns number of non-intersecting elements and optional arrays containing non-intersecting elements in first array (i3) and non-intersecting elements in second array (i4)

;EXAMPLE

;ARRAY(int) i1  
;i1[] = 1
;i1[] = 2
;i1[] = 3
;
;ARRAY(int) i2
;i2[] = 1
;i2[] = 3
;i2[] = 5
;
;
;ARRAY(int) i3 i4
;
;int i = ArrayNonInterSect_Int(i1 i2 i3 i4)
;if i3.len
,;out "i1  non-intersecting elements:"
,;for _i 0 i3.len
,,;out F"{i3[_i]}"
;else out "no i1 non-intersecting elements"
;out ""
;if i4.len
,;out "i1  non-intersecting elements:"
,;for _i 0 i4.len
,,;out F"{i4[_i]}"
;else out "no i4 non-intersecting elements"
;out ""
;out F"Total NonIntersecting elements = {i}"
;out F"Total NonIntersecting elements in s1 = {i3.len}"
;out F"Total NonIntersecting elements in s2 = {i4.len}"




int i j k
for i 0 i1.len
,;out F"{i} {s1[i]}"
,for j 0 i2.len
,,;out F"{s1[i]} vs {s2[j]}"
,,if i1[i] = i2[j]
,,,;out F"    {s1[i]} = {s2[j]} so break"
,,,goto g1;
,;out F"adding {s1[i]} to arrNonIntersect_arr1"
,arrintNonIntersect_arr1[] = i1[i]
,;g1
,continue
if arrintNonIntersect_arr1.len
,;out F"Total non-intersecting elements = {arrintNonIntersect_arr1.len}"
,if &i3
,,i3 = arrintNonIntersect_arr1

,;ret arrIntersect.len

for i 0 i2.len
,for j 0 i1.len
,,if i2[i] = i1[j]
,,,goto g2
,arrintNonIntersect_arr2[]    = i2[i]
,;g2
,continue
if arrintNonIntersect_arr2.len
,if &i4
,,i4 = arrintNonIntersect_arr2
ret arrintNonIntersect_arr1.len + arrintNonIntersect_arr2.len


,

Thanks, S
#2
With QM toolbars would be easier. Window triggers support regular expression in window name.

Toolbar Toolbar55
Trigger !a"$(Internet Explorer)|(Microsoft (PowerPoint|Excel|Word))|(Adobe Reader)"     Help - how to add the trigger to the macro
Code:
Copy      Help
Topmost :Zorder sub.Owner HWND_TOPMOST
Notopmost :Zorder sub.Owner HWND_NOTOPMOST


#sub Owner
function#
ret GetToolbarOwner(TriggerWindow)
#3
Yes thanks so much but I am sorry I didn't explain. This is for exe. I have to use workarounds because I can't use QM's excellent triggering system!!!
Any other thoughts for how to do in exe?
S
#4
Quote:I can't get them to get the TOPMOST message
Zorder() does not make window topmost?

Quote:any way to decrease the hit on the CPU usage?
Not very much CPU usage. Process Explorer shows:
0.02-0.03 % when this function does not run.
0.02-0.05 when runs without buttons.
0.12 with 1 button.
0.3 with 2 buttons.
#5
Sorry Gintaras, Zorder and ont both DO work. There was another thread grabbing the topmost Zorder.
The CPU usage stats were reassuring.
Thanks again!,
S


Forum Jump:


Users browsing this thread: 1 Guest(s)