Archived

This topic is now archived and is closed to further replies.

Windows is ignoring my code!??

This topic is 5577 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Could someone review this code (especially with the enumwindows() function) and tell me why it isn't working? Here's what's supposed to happen: if all windows are hidden from view then the TextOut command line will print out text to the screen. Here's what's happening: I can start the program up with a window showing (so no text should be drawn, right? right, and none is drawn...so far so good...) and no text is drawn..(good!).. however, if I minimize the window then text isn't drawn (when it should since it's showCmd should be equal to SW_HIDE.) It's like the EnumWindows() function isn't updating or something..I don't know does anyone know more about the details of this function (EnumWindows) and how it works or if I'm just using it wrong? I would have utilized the search engine, but unfortunately it's down. Anyhow, I know that people would recommend other ways to do what I am attempting to do here, but I want to try to at least get this to work. Here's the code....
  
#include <windows.h>
#include <stdio.h>

HWND window;
HWND hwnd;
HWND desktop_handle;
HDC hdc;
HRGN clip_region;
RECT parameter;
HDC HDC_Desktop;
int is_visible;
int should_draw;
WINDOWPLACEMENT window_param;

int end_loop = 0;

int window_count = 0;

BOOL CALLBACK GetAllWindowsProc( HWND hwnd, LPARAM lParam ) {

	should_draw = 0;
	
	GetWindowPlacement(hwnd,&window_param); 

	GetWindowRect(hwnd, ¶meter);

	if (window_param.showCmd == (SW_HIDE || SW_MINIMIZE )) {

        should_draw = 1;
		return true;

	}


	else {

		should_draw = 0;
		return false;

	}

	
	
} // end GetAllWindowsProc


int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdLine, int iCmdShow) { 
    
	HWND desktop_handle = GetDesktopWindow();

	HDC_Desktop = GetWindowDC(desktop_handle);

    while (true) {

		EnumWindows(GetAllWindowsProc, 0);
		
		if (should_draw) {

			HDC_Desktop = GetWindowDC(desktop_handle);
			char buffer_queue[256];
			sprintf(buffer_queue,"parameter.left = (%d)  parameter.right = (%d)  parameter.top = (%d)  parameter.bottom = (%d)" 
								 ,window_param.showCmd, parameter.right
								 ,parameter.top, parameter.bottom);
			TextOut(HDC_Desktop, 300,300, buffer_queue, strlen(buffer_queue));
			ReleaseDC(desktop_handle, HDC_Desktop);
		
		}
        
	}

return (0);
} 
  
thanks! ~Bolt [Edit: I put your code in a source box; see site FAQ for details.] [edited by - Oluseyi on September 10, 2002 5:50:49 AM]

Share this post


Link to post
Share on other sites
There are two problems that I can see right off.

The first has to do with the global variables used to store information about the enumerated windows. Those variables are only going to contain information about the last enumerated window. That is, each time through the function they are overwritten so when you get to the TextOut block the string to be displayed will only show information from the last window enumerated. If you want to retrieve information for every top level window, then you''ll need to allocate a large enough buffer to hold the information. To do that you''ll need to know how many windows there are ahead of time. What you might want to do instead is to make the HDC that you are writing to global and move the windowplacement and rect variables into to the enum loop along with the TextOut block and print the info for the given window each time through the function. You can use the lparam to pass along a line increment value so that TextOut doesn''t write over itself.

The second problem is that the enumeration will stop after it encounters the first visible window. That means that there will be some hidden or minimized windows that the enumeration won''t get too. If you want to enumerate through all of the top level windows you''ll have to return true for the visible windows as well. If you only want to display information regarding the hidden windows, place the TextOut block inside the appropriate block of the conditional.

Share this post


Link to post
Share on other sites
quote:
Original post by Boltimus
...however, if I minimize the window then text isn''t drawn (when it should since it''s showCmd should be equal to SW_HIDE.)

Are you sure about this? I don''t have any references before me, but I don''t think calling ShowWindow( hwnd, SW_HIDE ); is equivalent to minimizing the window.

Share this post


Link to post
Share on other sites
quote:
Original post by Oluseyi
Are you sure about this? I don''t have any references before me, but I don''t think calling ShowWindow( hwnd, SW_HIDE ); is equivalent to minimizing the window.


From the docs I have:
SW_HIDE Hides the window and activates another window.

And further:
quote:

Return Values
If the window was previously visible, the return value is nonzero.

If the window was previously hidden, the return value is zero.

Remarks
The first time an application calls ShowWindow, it should use the WinMain function''s nCmdShow parameter as its nCmdShow parameter. Subsequent calls to ShowWindow must use one of the values in the given list, instead of the one specified by the WinMain function''s nCmdShow parameter.

As noted in the discussion of the nCmdShow parameter, the nCmdShow value is ignored in the first call to ShowWindow if the program that launched the application specifies startup information in the STARTUPINFO structure. In this case, ShowWindow uses the information specified in the STARTUPINFO structure to show the window. On subsequent calls, the application must call ShowWindow with nCmdShow set to SW_SHOWDEFAULT to use the startup information provided by the program that launched the application. This behavior is designed for the following situations:

Applications create their main window by calling CreateWindow with the WS_VISIBLE flag set.
Applications create their main window by calling CreateWindow with the WS_VISIBLE flag cleared, and later call ShowWindow with the SW_SHOW flag set to make it visible.


Share this post


Link to post
Share on other sites
quote:
The second problem is that the enumeration will stop after it encounters the first visible window.


Yes. I wanted the EnumWindows() to stop as soon as any window was visible. Eventually I'll add an additional parameter to this conditional statement, but for now I just wanted to get this part of the code to work first.

The thing of it is, is that I tried something similar with a basic window (I retrieved the showCmd to see if it would be updated and with what number) anyhow it worked. The only difference is that instead of using EnumWindows() to get the hwnd for each window, I used the hwnd for the window I created (since I already knew it) and plugged it into the GetWindowPlacement() function and then displayed the parameter real time. It worked, so I'm assuming that's something's up with the EnumWindows(). Should I make a variable to track everytime the EnumWindowsProc is entered? Is there a time when it is never entered? I thought that even if windows were not visible it still enumerated through them. I did this once. I used a variable to track the number of times the Proc was entered with all windows minimized and the count continued to go up. Now this could be because of two reasons: 1.) the function was behaving normally or 2.) The EnumWindows() was still hung up on old data (it didn't update itself with the fact that all windows were now minimized and therefore hid. therefore it thought at least one window was visible and tried to enumerate throught it.)

Here's the code for the experiment with a simple window that DID work


  


// INCLUDES ///////////////////////////////////////////////

#define WIN32_LEAN_AND_MEAN // just say no to MFC


#include <windows.h> // include all the windows headers
#include <windowsx.h> // include useful macros
#include <stdio.h>
#include <math.h>


// DEFINES ////////////////////////////////////////////////


// defines for windows

#define WINDOW_CLASS_NAME "WINCLASS1"

// GLOBALS ////////////////////////////////////////////////

WINDOWPLACEMENT window_param;
HWND hwnd; // generic window handle

char buffer_queue[256];
HDC HDC_Desktop;
HWND desktop_handle;

// FUNCTIONS //////////////////////////////////////////////

LRESULT CALLBACK WindowProc(HWND hwnd,
UINT msg,
WPARAM wparam,
LPARAM lparam)
{
// this is the main message handler of the system

PAINTSTRUCT ps; // used in WM_PAINT

HDC hdc; // handle to a device context


// what is the message

switch(msg)
{
case WM_CREATE:
{
// do initialization stuff here


// return success

return(0);
} break;

case WM_PAINT:
{
// simply validate the window

hdc = BeginPaint(hwnd,&ps);
// you would do all your painting here

EndPaint(hwnd,&ps);

// return success

return(0);
} break;

case WM_DESTROY:
{
// kill the application, this sends a WM_QUIT message

PostQuitMessage(0);

// return success

return(0);
} break;

default:break;

} // end switch


// process any messages that we didn't take care of

return (DefWindowProc(hwnd, msg, wparam, lparam));

} // end WinProc


// WINMAIN ////////////////////////////////////////////////

int WINAPI WinMain( HINSTANCE hinstance,
HINSTANCE hprevinstance,
LPSTR lpcmdline,
int ncmdshow)
{

WNDCLASSEX winclass; // this will hold the class we create

MSG msg; // generic message


// first fill in the window class stucture

winclass.cbSize = sizeof(WNDCLASSEX);
winclass.style = CS_DBLCLKS | CS_OWNDC |
CS_HREDRAW | CS_VREDRAW;
winclass.lpfnWndProc = WindowProc;
winclass.cbClsExtra = 0;
winclass.cbWndExtra = 0;
winclass.hInstance = hinstance;
winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
winclass.hCursor = LoadCursor(NULL, IDC_ARROW);
winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
winclass.lpszMenuName = NULL;
winclass.lpszClassName = WINDOW_CLASS_NAME;
winclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

// register the window class

if (!RegisterClassEx(&winclass))
return(0);

// create the window

if (!(hwnd = CreateWindowEx(NULL, // extended style

WINDOW_CLASS_NAME, // class

"Your Basic Window", // title

WS_OVERLAPPEDWINDOW | WS_VISIBLE,
0,0, // initial x,y

400,400, // initial width, height

NULL, // handle to parent

NULL, // handle to menu

hinstance,// instance of this application

NULL))) // extra creation parms

return(0);

// enter main event loop

while (true)
{

desktop_handle = GetDesktopWindow();
HDC_Desktop = GetWindowDC(desktop_handle);
GetWindowPlacement(hwnd, &window_param);

sprintf(buffer_queue,"showCmd = (%d)", window_param.showCmd);
TextOut(HDC_Desktop, 300,300, buffer_queue, strlen(buffer_queue));

ReleaseDC(desktop_handle, HDC_Desktop);

GetMessage(&msg,NULL,0,0);

// translate any accelerator keys

TranslateMessage(&msg);

// send the message to the window proc

DispatchMessage(&msg);

} // end while


// return to Windows like this

return(msg.wParam);

} // end WinMain


///////////////////////////////////////////////////////////




I really don't see any difference between this code and the previous code except for the omission of the enumwindows. But the thing is, I need to know the handles only for VISIBLE windows, I don't care about minimized or hidden windows...

Thanks for all the help guys!!!

~Bolt

[edited by - Oluseyi on September 10, 2002 5:40:01 PM]

Share this post


Link to post
Share on other sites
Two things:

1. Look at the IsWindowVisible(HWND hWnd) function. It''s probably the one you want.

2. When you''re enumerating windows, check to see if the desktop window itself is enumerated -- that one will probably always be visible. Likewise, I don''t know if this is the case or not, but the taskbar, system tray, etc. are probably also visible windows.

What you probably want to do is build a list of "ignored visible windows" like the Desktop, Taskbar and System Tray. Then when you''re enumerating windows, ignore these if they come up.

HTH,

Cheers, dorix

Share this post


Link to post
Share on other sites
quote:
Original post by Boltimus
It worked, so I''m assuming that''s something''s up with the EnumWindows().


Um, more likely how you are using it.

quote:
Original post by Boltimus
Should I make a variable to track everytime the EnumWindowsProc is entered?


What for? In order to count the number of top level windows?

quote:
Original post by Boltimus
Is there a time when it is never entered?


As long as there are windows remaining to be enumerated and the EnumWindowsProc function returns true, windows will continue the enumeration.

quote:
Original post by Boltimus
I thought that even if windows were not visible it still enumerated through them.


As long as there are windows remaining to be enumerated and the EnumWindowsProc function returns true, windows will continue the enumeration.

quote:
Original post by Boltimus
I did this once. I used a variable to track the number of times the Proc was entered with all windows minimized and the count continued to go up. Now this could be because of two reasons: 1.) the function was behaving normally or 2.) The EnumWindows() was still hung up on old data (it didn''t update itself with the fact that all windows were now minimized and therefore hid. therefore it thought at least one window was visible and tried to enumerate throught it.)


The visibility state of a window has no effect on the enumeration. If the count changed from run to run it could be for many other reasons.

quote:
Original post by Boltimus
I need to know the handles only for VISIBLE windows, I don''t care about minimized or hidden windows...


Ok. The EnumWindowsProc from your first post stops the enumeration once it reaches the first visible window - if you want all visible windows you''ll have to work out another approach. Perhaps using IsWindowVisible as was suggested.

My advice is that you write a simple console prog to enumerate through all of the windows and to familiarize your self with the workings of EnumWindows - and then come back to the task you have set for yourself here.


Share this post


Link to post
Share on other sites
First I would like to thank LessBread and Oluseyi for their seemingly unending patience!! Anyhow, Dorix that was an excellent idea. I was thinking along the same lines while taking a shower and figured that if EnumWindows was indeed counting the desktop not to mention the other stuff (icons, taskbar, etc) as windows to be enumerated, then that would definitely "skew" my paradigm of EnumWindows(). I will look into this possibility and write concerning what I found. Once again good idea!!


~Bolt

Share this post


Link to post
Share on other sites
quote:
Original post by Boltimus
Sorry about the long code post Oluseyi, I accidentally put the [ code ] tag instead of the [ source ] tag, which is what I wanted to use... (thanks for the FAQ hint... )

Another GameDev miracle... you can edit your post to correct mistakes. Look in the upper-right corner of each post; you''ll see "edit" and "quote".

Share this post


Link to post
Share on other sites
quote:
Original post by Boltimus
First I would like to thank LessBread and Oluseyi for their seemingly unending patience!! Anyhow, Dorix that was an excellent idea. I was thinking along the same lines while taking a shower and figured that if EnumWindows was indeed counting the desktop not to mention the other stuff (icons, taskbar, etc) as windows to be enumerated, then that would definitely "skew" my paradigm of EnumWindows(). I will look into this possibility and write concerning what I found. Once again good idea!!


No problem from me Bolt As long as you learn something, that''s all that matters. A year from now I expect to see you helping other people

One thing to note about EnumWindows, in case you aren''t aware. The docs say that it enumerates all "top-level" windows. That doesn''t mean "windows that ride on top" or windows that you can see or might be able to see. A "top-level" window, is a window that might have child windows, but isn''t a child of any other window other than the desktop. To get a feel for the dozens of top-level windows currently present on your machine - head over to http://www.catch22.uk.net and grab a copy of WinSpy. The pop out right panel will show you every single window - top-level windows and their children - currently present on your machine.

Share this post


Link to post
Share on other sites
That''s a pretty cool little app! I''ll definitely have to get it. BTW, once I''m finished with this project im working on, it''s free to everyone who posted here! It''ll take a while and I''m not giving out any secrets but it''ll be worth the wait...now to that darn EnumWindows! hehe

~bolt

Share this post


Link to post
Share on other sites