I am creating a small utility to manage the windows of another application.
I set a timer to enumerate the windows. I must do this a number of times because a number of steps are involved. Let us call this other applicaton GM. Here's the pseudo code:
Check if the main window of GM is loaded.
If it is, check whether its child window DD is loaded.
If DD is loaded resize and reposition its window.
Also send key strokes to DD in order to have it open 4 more windows.
Check again to see whether these new windows are open. If they are, resize and reposition each of them.
My problem is that not all windows are being opened, and I am afraid this is a timing problem with the Windows messages. I am enumerating windows for each check. If you know of a better way, I am open to suggestions.
Now here are the main code blocks:
[TIMER EVENT START]
begin
if gOkToRun then
begin
gOkToRun := false;
// enumerate windows and check for GMisLoaded and terminate as necessary
gGMisLoaded := False;
EnumWindows(@GMCheck,LongInt(Self));
if (not gGMisLoaded) then
mnuExitClick(Self)
else
begin
// enumerate windows and check for Debug session activity
gDebugLoaded := false;
EnumWindows(@DebugCheck,LongInt(Self));
sleep(1000);
if gDebugLoaded and gDebugSet then
begin
if not gWindowsSet then
begin
// enumerate windows and set up Debug windows (one time per debug session)
EnumWindows(@ResetWindows,LongInt(Self));
gWindowsSet := true;
end;
end
else
begin
gDebugSet := false; //loaded watch and debug info widows
gWindowsSet:= false; //resized and repositioned debug info widows
GMDAMain.ListBox1.Clear;
end;
end; // end else if (not gGMisLoaded)
end;
gOkToRun := true;
[TIMER EVENT END]
[OPEN CHILD WINDOWS]
var i : Integer;
begin
for i := 0 to gMaxWindows-1 do
begin
// messagedlg(IntToStr(i),mtInformation,[mbOK],0);
if (wRecord.open = 1) then
begin
if (wRecord.name = 'Messages') then
begin
OpenMessages(Wnd);
sleep(250);
end;
if (wRecord.name = 'Global Variables') then
begin
OpenGlobal(Wnd);
sleep(250);
end;
if (wRecord.name = 'All Instances') then
begin
OpenInstances(Wnd);
sleep(250);
end;
end;
end;
end;
[OPEN CHILD WINDOWS END]
This is a sample of the code which sends key strokes. I have one of these for each window I need to open.
[CODE START]
procedure TGMDAMain.OpenMessages(Wnd: Hwnd);
//----------------------------------------------------------------------]]
begin
if (Wnd <> 0) then
begin
SetForegroundWindow(Wnd);
Sleep( 250 );
// Alt-&Watch
keybd_event( VK_MENU, Mapvirtualkey( VK_MENU, 0 ), 0, 0 );
keybd_event( Ord('T'), MapVirtualKey( Ord('T'), 0), 0, 0 );
keybd_event( Ord('T'), MapVirtualKey( Ord('T'), 0), KEYEVENTF_KEYUP, 0 );
keybd_event( VK_MENU, Mapvirtualkey( VK_MENU, 0 ), KEYEVENTF_KEYUP, 0 );
// &Load
keybd_event( Ord('M'), MapVirtualKey( Ord('M'), 0), 0, 0 );
keybd_event( Ord('M'), MapVirtualKey( Ord('M'), 0), KEYEVENTF_KEYUP, 0 );
End;
End;
[CODE END]
I set a timer to enumerate the windows. I must do this a number of times because a number of steps are involved. Let us call this other applicaton GM. Here's the pseudo code:
Check if the main window of GM is loaded.
If it is, check whether its child window DD is loaded.
If DD is loaded resize and reposition its window.
Also send key strokes to DD in order to have it open 4 more windows.
Check again to see whether these new windows are open. If they are, resize and reposition each of them.
My problem is that not all windows are being opened, and I am afraid this is a timing problem with the Windows messages. I am enumerating windows for each check. If you know of a better way, I am open to suggestions.
Now here are the main code blocks:
[TIMER EVENT START]
begin
if gOkToRun then
begin
gOkToRun := false;
// enumerate windows and check for GMisLoaded and terminate as necessary
gGMisLoaded := False;
EnumWindows(@GMCheck,LongInt(Self));
if (not gGMisLoaded) then
mnuExitClick(Self)
else
begin
// enumerate windows and check for Debug session activity
gDebugLoaded := false;
EnumWindows(@DebugCheck,LongInt(Self));
sleep(1000);
if gDebugLoaded and gDebugSet then
begin
if not gWindowsSet then
begin
// enumerate windows and set up Debug windows (one time per debug session)
EnumWindows(@ResetWindows,LongInt(Self));
gWindowsSet := true;
end;
end
else
begin
gDebugSet := false; //loaded watch and debug info widows
gWindowsSet:= false; //resized and repositioned debug info widows
GMDAMain.ListBox1.Clear;
end;
end; // end else if (not gGMisLoaded)
end;
gOkToRun := true;
[TIMER EVENT END]
[OPEN CHILD WINDOWS]
var i : Integer;
begin
for i := 0 to gMaxWindows-1 do
begin
// messagedlg(IntToStr(i),mtInformation,[mbOK],0);
if (wRecord.open = 1) then
begin
if (wRecord.name = 'Messages') then
begin
OpenMessages(Wnd);
sleep(250);
end;
if (wRecord.name = 'Global Variables') then
begin
OpenGlobal(Wnd);
sleep(250);
end;
if (wRecord.name = 'All Instances') then
begin
OpenInstances(Wnd);
sleep(250);
end;
end;
end;
end;
[OPEN CHILD WINDOWS END]
This is a sample of the code which sends key strokes. I have one of these for each window I need to open.
[CODE START]
procedure TGMDAMain.OpenMessages(Wnd: Hwnd);
//----------------------------------------------------------------------]]
begin
if (Wnd <> 0) then
begin
SetForegroundWindow(Wnd);
Sleep( 250 );
// Alt-&Watch
keybd_event( VK_MENU, Mapvirtualkey( VK_MENU, 0 ), 0, 0 );
keybd_event( Ord('T'), MapVirtualKey( Ord('T'), 0), 0, 0 );
keybd_event( Ord('T'), MapVirtualKey( Ord('T'), 0), KEYEVENTF_KEYUP, 0 );
keybd_event( VK_MENU, Mapvirtualkey( VK_MENU, 0 ), KEYEVENTF_KEYUP, 0 );
// &Load
keybd_event( Ord('M'), MapVirtualKey( Ord('M'), 0), 0, 0 );
keybd_event( Ord('M'), MapVirtualKey( Ord('M'), 0), KEYEVENTF_KEYUP, 0 );
End;
End;
[CODE END]