Link to home
Start Free TrialLog in
Avatar of j4months
j4months

asked on

screen coordinate?

How do I launch a GUI at a specified location as I choose?
For example, everytime I do system("explorer.exe"); an explorer window comes up at a different spot.

My purpose is to create a demo of using a GUI. I need to use the RECORD and PLAYBACK hooks which are systemwide hooks. If the GUI starts up at a different spot everytime, I cannot guarantee that a mouse click is going to be at the right place when playback-ed.
Avatar of wenderson
wenderson

Instead of using system, use CreateProcess, so you can control other aspects of the creation, like the size em position of the main window.

Wenderson
Avatar of j4months

ASKER

I tried the following, but it doesn't work, the position still varies every time I run the program...
----------------------------
PROCESS_INFORMATION pInfo;
STARTUPINFO StartInfo;
//GetStartupInfo(&StartInfo);
  .......
StartInfo.dwFlags=STARTF_USEPOSITION;
StartInfo.dwX=0;
StartInfo.dwY=0;
CreateProcess(NULL,"explorer.exe",NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS,NULL,NULL,&StartInfo,&pInfo);
 ....
Some Windows programs are always created the same position it was when it closed the last time.

You may use MoveWindow ou SetWindowPos to position them where you want.

Wenderson
how do I get the handle of the window?
I think you forgot this question. I will ask Community Support to close it unless you finalize it within 7 days. Unless there is objection or further activity,  I will suggest to refund the points and PAQ at zero points since nobody had a complete answer for you.

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
======
Werner
Sorry, I got into the wrong window ...

======
Werner
When you create a process, CreateProcess or ShellExecuteEx returns the process and thread id of the process, you may use FindWindow or EnumWindows to get the active windows, and then, call GetWindowThreadProcessId and compare the process id with the one you have.

Wenderson
It still doesn't work. (as if I haven't done anything...) Here is what I did.  Anything wrong with this code? (OnStart is a button event handler. )
Thanks.
---------------
void CSomeDlg::OnStart()
{
  CreateProcess(NULL,"explorer.exe",NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS,NULL,NULL,&StartInfo,&pInfo);
  pid=pInfo.dwProcessId;
  EnumWindows(EnumWindowsProc, pid);
}

BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lparam){
  DWORD wndPID;
  GetWindowThreadProcessId(hwnd,&wndPID);
  if(wndPID==(DWORD)lparam)::MoveWindow(hwnd,10,10,300,400,TRUE);
  return true;
}
I know it may sound strange, but your code is too fast, when you create a process, it takes some time for the module to be loaded and the window to be created, but CreateProcess does not wait until the end, so it seams that EnumWindow is not finding the newly created window.
I changed your code slightly and put a Sleep(1000) after CreateProcess and before EnumWindows, and it's working fine, I also compiled as Unicode, but should make no diference, I think.

Wenderson

#include <stdio.h>
#include <windows.h>

BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lparam)
{
     DWORD wndPID;
     GetWindowThreadProcessId(hwnd,&wndPID);
     if(wndPID==(DWORD)lparam)
     {
          MoveWindow(hwnd,10,10,300,400,TRUE);
     }

     return true;
}

void Start()
{
     PROCESS_INFORMATION pInfo;

     wchar_t CmdLine[256] = L"explorer.exe";

     STARTUPINFO StartInfo;
     memset(&StartInfo, 0, sizeof(STARTUPINFO));
     StartInfo.cb = sizeof(STARTUPINFO);

     CreateProcess(NULL, CmdLine, NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS,NULL,NULL,&StartInfo,&pInfo);
     Sleep(1000);
     EnumWindows(EnumWindowsProc, pInfo.dwProcessId);
}

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
     Start();
     return 0;
}
If I simply add "::Sleep(1000)" to my code, it still acts the same as before.

For me to be able to compile your program, I have to change the "wchar_t" line to:
 char CmdLine[256] = "explorer.exe";

The resulting executable starts the NT explorer window at different places every time..
That because I compiled as Unicode and you are probably using ASCII.
Trying changing the application you are running, use for example "notepad.exe" instead of "explorer.exe", and also, try to debug the application, step by step, to see if the window has been found correctly.
What's your system?
I tested it under Windows 2000 on a Pentium II 400MHz with 192MB.

Wenderson
notepad.exe works. So why notepad works while explore.exe doesn't? What about my own executable (GUI)? what if my GUI is written in Java?

I am using NT 4.0, I need to do custom installation of Visual C++ 6.0 to include Unicode.
I think there is no need for you to install Unicode, you can use ASCII.
And the explorer or your application are not working because of the time they take to load and initialize the main window, they may be too heavy and probably, they take too many time to start, try increasing the delay, or call EnumWindows several times, until you find the window.

Wenderson
I think I have given Explorer enough sleep time, the window just doesn't move..

I follow the msdn help and reinstall unicode, I check to see that I do have the file "UAFXCW.lib". so I unicode support? However, I still cannot compile your program:

"error C2664: 'CreateProcessA' : cannot convert parameter 2 from 'unsigned short [256]' to 'char *' Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast"
To compile as Unicode you need to define UNICODE and _UNICODE in the settings of your project.
I did not tested under NT4, but I can do it and get back to you soon.

Wenderson
In project settings, C/C++ preprocessor definitions, I added UNICODE,_UNICODE, and it compiles OK, but the problem still exists.

I think it's the OS..?
Thanks (I'll up the points.)
Please update and finalize this old, open question. Please:

1) Award points ... if you need Moderator assistance to split points, comment here with details please or advise us in Community Support with a zero point question and this question link.
2) Ask us to delete it if it has no value to you or others
3) Ask for a refund so that we can move it to our PAQ at zero points if it did not help you but may help others.

EXPERT INPUT WITH CLOSING RECOMMENDATIONS IS APPRECIATED IF ASKER DOES NOT RESPOND.

Thanks,

** Mindphaser - Community Support Moderator **

P.S.  Click your Member Profile, choose View Question History to go through all your open and locked questions to update them.
I suggest to

     "refund the points and PAQ at zero points"

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
======
Werner
ASKER CERTIFIED SOLUTION
Avatar of Mindphaser
Mindphaser

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial