|
Hi,
I would like to know if there is a way to switch windows focus to another application thats already running from a current application?? For example, I have two MFC applications (each application uses up one screen of the two screens connected to the system) running on a system, I spend most of the time running one of those applications, but occasionally I wanna do a quick click on another application, I dont want to waste time to drag mouse and check where the button on the other application is to click on it.
So is there a way to achieve this??
-Pavan
PKNT
|
|
|
|
|
Kiran Satish wrote: I would like to know if there is a way to switch windows focus to another application thats already running from a current application??
SetForegroundWindow()?
Kiran Satish wrote: but occasionally I wanna do a quick click on another application
That's different than just setting the focus to another application.
Do you want to click a button in another app remotely?
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Thanks for answering my questions, actually the two applications(app1, app2) are on the same system, I just want to set focus to another application(app2) when I click a button/keyboard character in app1. Once I set the focus onto app2 I can read another keystroke thats now will be read in app2 and do appropriate work.
From MSDN it says- BOOL SetForegroundWindow( HWND hWnd ); How can I get handle for app2 in app1?? They both are started individually.
-Pavan.
PKNT
|
|
|
|
|
No matter what you use, you're going to need to know something
about the other process.
In this case, you need to know the other process' HWND.
FindWindow() can help if you know what you're looking for.
GetWindowThreadProcessId() may be useful as well.
It depends what info you have to identify the other process.
Once you have the window handle, you can use SetForegroundWindow()
to activate it. You should then call GetLastActivePopup(), and if it returns
a different window handle then the one you activated, call
SetForegroundWindow() on that window.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
This question is not completely related to this thread, but while working on the above, I came accross a situation where I need to get keyboard events and I am trying to use WM_KEYDOWN function to capture the events from a dilaog window thats created in a main dialog application, I tried it directly in main dialog window also, but it does nothing. I had a message box in it to pop up whenever it enter OnKeyDown() function.
I know it works, because I used the same way in another application which is in Doc/View architecture. Am I doing anything wrong here??
-Pavan.
PKNT
|
|
|
|
|
Generally, the problem is that only one window at a time can
have keyboard focus. In a dialog, it's usually one of the controls
in the dialog that has the keyboard focus, not the dialog itself.
This means you need to either
a) Handle the WM_KEYDOWNMESSAGE in the appropriate
window (control) (sub)class or
b) Override CWinApp::PreTranslateMessage() and filter every WM_KEYDOWN
that is sent on the thread.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I tried to use the override method, but I have some problems in reading the key code from it.
BOOL CMyApp::PreTranslateMessage(MSG* pMsg) <br />
{<br />
if(pMsg->message == 256)
MSGFILTER * lpMsgFilter = (MSGFILTER *)pMsg->wParam;<br />
<br />
return CDialog::PreTranslateMessage(pMsg);<br />
}
When I try to read the message into lpMsgFilter and check in debug, it is having NULL values in it and the application gives Unhandled exception..:Access Violation error. Is there any other way to read the keycode??
-Pavan.
PKNT
|
|
|
|
|
You can't call the CDialog PreTranslateMessage() from there.
I'm not sure how that even compiled.
You should be calling the base class' method.
If the message is WM_KEYDOWN, wParam is the virtual key code,
not a pointer.
Also, why would you hardcode 256 instead of using WM_KEYDOWN?
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Its working and I can read the key codes directly from value passed by PreTranslateMessage.
Coming back to focuswindow, I am trying to focus another child window from other child window (both are in the same main application) and want to focus all my keystrokes on a particular button on that child window. Then, any keystrokes even like space bar should be applied to that button, at present as soon as I change focus to the child window and when I press spacebar, it applies it to the first button that I created while creating the dialogbox. How can i change this behavior, tried SetDefId(ID) and it doesnt help either.
I am using WM_KEYDOWN only, not 256 (I used it just like tht nothing particular).
Any suggestions??
thanks,
-Pavan.
PKNT
|
|
|
|
|
You should be setting focus to the button if you want the button to have focus.
If you set focus to the button's parent, yo'll get focus at whatever control
the parent passes focus to.
You can post WM_NEXTDLGCTL to the parent to set focus to a certain control
in the window.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I am trying in this way and it still goes to the default button on that window that I created first.
I have three dialogs (main dialog, child dialog1, child dialog2), now I am trying to set focus onto dialog2 from dialog1 and also set the control to button4 on dialog2 and it always goes to button1 on dialog2 as soon as I set the focus on dialog2.
<br />
(parent->dialog2)->SetFocus();<br />
CButton *Button;<br />
Button=(CButton *)GetDlgItem(IDB_GRAB);<br />
(parent->dialog2)->PostMessageA(WM_NEXTDLGCTL,Button->GetDlgCtrlID(),TRUE);
Is it correct??
-Pavan.
PKNT
|
|
|
|
|
Kiran Satish wrote: Is it correct??
No.
(parent->dialog2)->SetFocus();<br />
CButton *Button;<br />
Button=(CButton *) (parent->dialog2)->
GetDlgItem(IDB_GRAB);<br />
(parent->dialog2)->PostMessageA(WM_NEXTDLGCTL,(WPARAM)(HWND)*Button,TRUE);
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Yep that works PERFECT... thanks alot. Feeling stupid for asking you soo many silly(stupid??) questions. More to come...
Yep here it is another one..
If I have an MFC applicaiton with executable, how can I pass command line arguments to it, I would like to pass a file name to an exe file created in MFC when executing at command prompt??
-Pavan.
PKNT
|
|
|
|
|
You're welcome
Kiran Satish wrote: how can I pass command line arguments to it
How do you pass them or how do you retrieve them?
To pass them, you can add them to a shortcut in the shell.
Programmatically, they can be included with CreateProcess().
To retrieve them, add this to your app class InitInstance() override:
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
CString FileNameStr = cmdInfo.m_strFileName;
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I got it, its quite easy, I shoulda looked on MSDN before asking here (a minute difference). SOrry for wasting ur time there....
-Pavan.
PKNT
|
|
|
|
|
Does anyone know how to add and retrieve the objects of a class to/from a deque container? I am building a larger project with a similar problem but I cannot even get the basics to work.
int main () {
deque<int> Test2;
Test2.push_back(3);
Test2.push_back(4);
Test2.push_back(5);
<p></p>
Patient p;
deque< Patient> TestQue;
<p></p>
p.SetAge("20");
p.SetName("Dave");
p.SetCode("GEN");
<p></p>
TestQue.push_back(p);
<p></p>
cout << "Test: " << TestQue[0];
<p></p>
cout << "Test: " << Test2[0] << " " << Test2[1] << " " << Test2[2] << "\n";
<p></p>
system ("pause");
return EXIT_SUCCESS;
}
********************************************************
"Patient.h" procedure below:
This is part of a doctor class but I don't need it for this particular question.
********************************************************
class Patient {
private:
char* LastName;
char* Age;
char* Code;
public:
Patient();
Patient (char *, char *, char *);
void SetName(char *);
void SetAge(char *);
void SetCode(char *);
char* GetName();
char* GetAge();
char* GetCode();
~Patient();
};
********************************************************
Patient Procedure Below
********************************************************
#include "Patient.h"
Patient::Patient() {
LastName = NULL;
Age = NULL;
Code = NULL;
}
Patient::Patient(char *last, char *age, char *code) {
LastName = _strdup(last);
Age = _strdup(age);
Code = _strdup(code);
}
void Patient::SetName (char* last) { LastName = _strdup(last); }
void Patient::SetAge (char* age) { Age = _strdup(age); }
void Patient::SetCode (char* code) { Code = _strdup(code); }
<p></p>
char* Patient::GetName() { return LastName; }
char* Patient::GetAge() { return Age; }
char* Patient::GetCode() { return Code; }
|
|
|
|
|
PolarFuzz wrote: cout << "Test: " << TestQue[0]; // I cannot retrieve class objects, does not compile
What is the compiler complaining about?
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
I believe when an object gets assigned to a STL container, it gets copied into it. Your class does not have a "custom" copy constructor or a "custom" assignment operator.
-- modified at 11:59 Thursday 4th October, 2007
"We make a living by what we get, we make a life by what we give." --Winston Churchill
|
|
|
|
|
Perhaps not. The default would be used and the object in the container would have copied the pointers and since in his main code the Patient is still on the stack the pointers would be good. Of course he needs deep copy and assignment but appears to be a student so I would be surprised if he has any idea of this stuff.... yet.
|
|
|
|
|
True. It just makes me nervous to see classes working with memory allocation w/o a copy constructor and a assignment operator. Also, he has no destructor to clean up.
"We make a living by what we get, we make a life by what we give." --Winston Churchill
|
|
|
|
|
Well hopefully he will have a better understanding of such things by the end of the course.
|
|
|
|
|
For compiler errors you need to post the error message.
A wild guess based on your code is the output stream knows how to output an int but doesn't know how to output a Patient.
|
|
|
|
|
At a guess, I would say your Patient needs to define an “<<” operator that uses “std::stringstream” internally to convert the data to a string that is returned for “cout” to process. I could be wrong as do not remember doing that before, so look around for an example.
What worries me more is what the Patient’s destructor does, as you did not show it. In your code you have two Patients’ and they both contain memory pointers to the same address. You have the original and the copy in the “deque”, when they go out of scope then the destructor will be called for both of them. That means that the same memory will be being freed twice, always a bad idea. Also if the original Patient was created in a different scope and goes out of scope before the “deque” does, the pointers in the copy, contained in the “deque” will be pointing to unallocated memory or memory that is being used my someone else; very, very bad thing.
You need a copy constructor the makes a copy of the original by allocating new memory for the data. This can be done by simply duplicating the code in “Patient(char*,char*,char*)” within the copy constructor.
Additionally you need to make sure that the “char*” passed points to something before calling “_strdup”, as I do not know what will happen if it points to NULL. Also before you assign a new address to a pointer in your methods/functions, you need to make sure that if the pointer is already assigned to a different address that it is freed before making the new assignment.
Of course you could eliminate all that pointer stuff by simply using the “std::string”, instead of handling yourself. It will handle all the memory allocation and copying for you and make the code much cleaner and easier to read.
Properly applied, usage of the STL can eliminate most, if not all, of the memory allocations you need. Take full advantage of “std:string”, “std::vector”, and other containers; after all that are what they are for.
Well that ends today’s lesson. I hope it helped.
INTP
"Program testing can be used to show the presence of bugs, but never to show their absence."Edsger Dijkstra
|
|
|
|
|
I will probably fix the destructor stuff later. I THINK the program crashes because it is recalling non-existant values from the patient class that no longer exist or out of scope. I originally tried to define the deque with the definition of the doctor class (doctor.h) below:
#include "Patient.h"
#include <deque>
<p></p>
class Doctor {
<p></p>
private:
char* LastName;
char* Room;
char* Code;
deque<patient> PatientQue;
<p></p>
public:
Doctor();
Doctor (char *, char *, char *);
void SetName(char *);
void SetRoom(char *);
void SetCode(char *);
void SetPatientQue (Patient);
char* GetName();
char* GetRoom();
char* GetCode();
Patient GetPatientQue();
};
If I could define it here, then I think my problem would be solved. However, I get an error message, something about a semicolon that is expected before the "<". All the other code within the doctor procedure was just a work-around because this did not work.
Do you know how to define a deque within the class header?
|
|
|
|
|
I have seen that error many times, but all I know at the moment is that something is missing. The error message is [technically] wrong! My first thought was that you did not use “std::deque”, or a using statement (I never do in C++), but that was wrong. Look in your header file and try to see if you are missing something; that is my first reaction. Beyond that I do not know, because I have always found the problem and did not bother to think about it beyond that. You have a syntax error, some minor one, but one just the same.
As noted in my last post, I highly recommend that you stop using “char*” and start using “std::string” for the reasons I gave. The method in your original post mixed C and C++, and the C++ solution (STL) for handling strings is much better if memory allocation is involved.
If you gave the error number it might help a little, and I stress little, because the description you just gave (this time) is good enough. The exact cause could be a number of things (I think), but unless you (meaning myself) are the one doing the debugging, it is unpredictable.
Most of the time that you find yourself doing a work-around, there is something wrong with the original code or you are making some minor mistake (which I do not see).
I know that was of no help, but please consider what I said about “std::string”. Even if you only use them internally to your class, you will save yourself a lot of trouble.
P.S. Also make those parameters constant (“const char*”).
INTP
"Program testing can be used to show the presence of bugs, but never to show their absence."Edsger Dijkstra
|
|
|
|