|
AFAIK, Your process of setting up the hook, Forwarding calls to the window(HOOK) procedure and then releasing the hook should be performed inside the dll. The messages are then captured by the dll before they are passed on to any application.
Somethings seem HARD to do, until we know how to do them.
_AnShUmAn_
|
|
|
|
|
Hm... no luck with that either. I added this code to my dll.
void APIENTRY StartHook()
{
if (!gHinstance)
return;
g_hHook = SetWindowsHookEx(WH_CBT, CBTProc, gHinstance, 0);
return;
}
void APIENTRY StopHook()
{
if (g_hHook)
UnhookWindowsHookEx(g_hHook);
}
This to my application
if (dllModule)
{
StartHookProcPtr = (VOIDPROC) GetProcAddress(dllModule, "StartHook");
(StartHookProc)();
}
|
|
|
|
|
When you use global hooks you are effectively writing a distributed application. The calls to OutputDebugString are being called in the context of the application which creates the window ***NOT*** the process which installs the hook - this is the nature of global hooks and why they're so dangerous to overall system stability if written incorrectly. In short, your code may be working but you're looking in the wrong place for the debug messages.
Steve
|
|
|
|
|
You may vote me down but if the calls to OutputDebugString are replaced with calls to something like MessageBeep you may find I'm correct.
Steve
|
|
|
|
|
Replace the calls to OutputDebugString with MessageBeep(-1) and make sure your sound is turned up. Before you do this make sure that MessageBeep(-1) produces an audible beep in a stand-alone program. Do you hear a beep when a window is created in another process?
Steve
|
|
|
|
|
Hi Steve,
Yo Da Man! Yes, it does beep like crazy when I replaced OutputDebugString with MessageBeep.
Thanks so much for the help!
|
|
|
|
|
|
Strange thing. When my hook function is invoked and I try to access the lpszClass value, it will crash the application if it's hooked to its thread id, or visual studio, explorer and everything else (I have to reboot the computer...) if I specify 0 as the thread id in SetWindowsHookEx
I just need to detect if the window class is of a specific name. If I comment out the _tcsstr line the crash will go away, but then I can't detect the specific window. I vaguely remember seeing a bad pointer value in the debugger, but I'm already checking the pointer before using it. Could it be some windows are not initialized properly?
LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode == HCBT_CREATEWND)
{
CBT_CREATEWND* wndData = (CBT_CREATEWND*)lParam;
if (wndData && wndData->lpcs)
{
if (wndData->lpcs->lpszClass)
{
if (_tcsstr(wndData->lpcs->lpszClass, _T("the window class name")))
{
}
}
}
}
return ::CallNextHookEx(0, nCode, wParam, lParam);
}
|
|
|
|
|
jipai wrote: LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
have u exported the above function?
nave
|
|
|
|
|
Yup.
LIBRARY "My"
EXPORTS
; Explicit exports can go here
StartHook
StopHook
CBTProc
|
|
|
|
|
See Hooks[^] maybe it is some helpful to you
|
|
|
|
|
Thanks for the info. Good to know.
|
|
|
|
|
I hope it solve your problem
|
|
|
|
|
I have created a MFC project in Visual C++ .NET. My goal is read in what is coming from COM port 4.
Here is the entire function below with some comments on what happens:
<br />
BOOL CReadComDlg::ConfigureCOMPort()<br />
{<br />
CString strPort;<br />
BOOL fSuccess;<br />
iCOMPortNumber = 4;
<br />
strPort.Format("COM%d", iCOMPortNumber) ;<br />
<br />
m_hFile = CreateFile( strPort, <br />
GENERIC_READ | GENERIC_WRITE,<br />
(DWORD)NULL,
NULL,
OPEN_EXISTING,<br />
FILE_ATTRIBUTE_NORMAL,<br />
NULL );
<br />
if (INVALID_HANDLE_VALUE == m_hFile)<br />
{<br />
AfxMessageBox( "ERROR 2: unable to connect to COM port." );<br />
return FALSE;<br />
}<br />
<br />
<br />
SetupComm( m_hFile,
(DWORD)2048,
(DWORD)2048);
<br />
<br />
DCB dcb;<br />
fSuccess = GetCommState(m_hFile,&dcb);<br />
<br />
if (!fSuccess) <br />
{<br />
DWORD dError = GetLastError();<br />
<br />
AfxMessageBox ("Error 3: Failed to Get the System Communication Settings.", MB_OK|MB_ICONEXCLAMATION );<br />
return FALSE;<br />
}<br />
.<br />
.<br />
.<br />
.<br />
}<br />
Both functions return error code 995: ERROR_OPERATION_ABORTED = The I/O operation has been aborted because of either a thread exit or an application request.
What does this mean? What am i doing wrong? When I use hyperterminal to setup the connection it works fine. I want to be able to receive data from the COM port. I don't even want to send anything out to the COM port.
If anyone has any suggestions, helpful links, or sample code that would be very helpful. Thank you for your time.
|
|
|
|
|
Hello!
I've made a simple application. When I click a button in mian window a modal popup window shows up:
Ustawienia modalne;
modalne.DoModal();
I want that when I click OK in this modal wnd. it changes a Static Text in main wnd.:
void Modalne::OnBnClickedOk()
{
UpdateData(true);
((CNoweOknoDlg*)m_pParent)->m_text1 = "tekst";
((CNoweOknoDlg*)m_pParent)->UpdateData(false);
OnOK();
}
When I press this button the app crasches
When I made this popup wnd. as modeless using Create() funtion everything is OK. :/
|
|
|
|
|
You should expose the string on your dialog and set the text in your main window. Apart from anything else, your approach makes the two forms tightly coupled for no good reason.
Christian Graus - Microsoft MVP - C++
Metal Musings - Rex and my new metal blog
|
|
|
|
|
|
Which bit are you confused by ? Expose a parameter to store the value you want to return, do the rest in your main dialog if the modal call returns OK.
Christian Graus - Microsoft MVP - C++
Metal Musings - Rex and my new metal blog
|
|
|
|
|
m_text1 is a CString value that represents static text in mian window. To change it I have to call this:
((CNoweOknoDlg*)m_pParent)->m_text1 = "text"
on button click. I don't have any idea how to do this in a different way.
I'm confused why it works with modeless window.
|
|
|
|
|
OK, so you didn't understand anythign I said ?
I'm not sure why it doesn't work, but either way, when class 1 needs to know about the internals of class 2, they are tightly coupled, and thus cannot work without each other. You're doing this in your OnOK method, so I assume it happens as the dialog closes. so, what you want to do is, the code in CNowkOKnoDlg, your main class, will create this child form and show it. Assuming that "text" is going to become a variable, add a public string variable, then set m_text1 inside the class that holds that variable, and created the dialog that sets it.
Christian Graus - Microsoft MVP - C++
Metal Musings - Rex and my new metal blog
|
|
|
|
|
Christian Graus wrote: Assuming that "text" is going to become a variable, add a public string variable, then set m_text1 inside the class that holds that variable, and created the dialog that sets it
Christian I think even I am misunderstanding you.
Are you suggesting something of the following nature?
CFoo dlg
Dlg.m_text1 = "the test string"
Dlg.Domodal();
Isn’t is safer to
CFoo dlg<br />
<br />
<br />
Dlg.SetMyText("the test string");<br />
Dlg.Domodal();
I'd love to help, but unfortunatley I have prior commitments monitoring the length of my grass. :Andrew Bleakley:
|
|
|
|
|
Yes, you are misunderstanding me. Or I'm misunderstanding you. I thought you were setting a string in the main window from the modal dialog. I am saying, set the string in the main window, and expose a property on the dialog to tell you what the string is.
A get method makes more sense than a public property, that much is true. I was just trying to keep it simple.
Christian Graus - Microsoft MVP - C++
Metal Musings - Rex and my new metal blog
|
|
|
|
|
Christian Graus wrote: I thought you were setting a string in the main window from the modal dialog. I am saying, set the string in the main window, and expose a property on the dialog to tell you what the string is.
Wasn't me, I was just bored perusing the message boards noticed the question and which made no sense (at least to me)
Posting a string back a parent dialog is always a pain, so far I have always found it better to just wait until the modal child closes then follow what you said and use a getter. Shrugs, lol not really my problem I was just confused by the question and responses.
I'd love to help, but unfortunatley I have prior commitments monitoring the length of my grass. :Andrew Bleakley:
|
|
|
|
|
What I believe Christian is trying to say here is do something to the following affect.
CFoo Chlddlg<br />
<br />
<br />
if(IDOK == Chlddlg.Domodal())<br />
{<br />
CString str = Chlddlg.GetMyText();<br />
SetWindowText(str);<br />
}
Dont try and post the string back to the parent dialog, let the parent collect it from the child. This protects the inner workings of both classes. GetMyText() could return any variation of data. (this is just a simple example).
I'd love to help, but unfortunatley I have prior commitments monitoring the length of my grass. :Andrew Bleakley:
|
|
|
|
|
if you want to change the text of a control you can do this :
void CMdlDlg::OnOkButton()
{
CWnd *parent = this->GetParent();
parent->SetDlgItemText(" control ID ","new text");
}
or if you want to change the main dialog tilte then do this :
void CMdlDlg:;OnOkButton()
{
(this->GetParent())->SetWindowText("new text");
}
|
|
|
|