Click to See Complete Forum and Search --> : static trouble :(


dave2k
November 20th, 2005, 09:29 AM
ok, i have bool Window::SetHook()
{
// Find the child RICHEDIT control and return its handle
HWND hwndCntrl = ::FindWindowEx(hwnd, 0, "RICHEDIT", 0);

if(::IsWindow(hwndCntrl))
return false;

// Load HookProc.dll
hinstDLL = ::LoadLibrary((LPCTSTR) "HookProc.dll");
HOOKPROC hkprcSysMsg = (HOOKPROC)GetProcAddress(hinstDLL, "CallWndProc");

// Set the hook
DWORD ThreadIdCntrl = GetWindowThreadProcessId(hwndCntrl, 0);
HHOOK hh = ::SetWindowsHookEx(WH_CALLWNDPROC, hkprcSysMsg, hinstDLL, ThreadIdCntrl);

return true;
}

i amtrying to set a hook in the class function above ^

i get the following : Test error LNK2001: unresolved external symbol "private: static struct HINSTANCE__ * Window::hinstDLL" (?hinstDLL@Window@@0PAUHINSTANCE__@@A)


Why is this? my header looks likeclass Window
{
public:
~Window();
BOOL Find (string);
string windowText; // title of poker window
HWND hwnd; // handle of poker window
bool SetHook(); // attempt to hook the RICHEDIT control

private:
//HOOKPROC hkprcSysMsg;
static HINSTANCE hinstDLL;
static BOOL CALLBACK EnumWindowsProc (HWND hWnd, LPARAM lParam);
HHOOK hh;

};


cheers

NoHero
November 20th, 2005, 09:40 AM
Any static member (if method or data member) must be initialized (implemented for methods and initialized for data members). So go and initialize your static member in your cpp file:

HINSTANCE Window::hinstDLL = NULL;

And btw: It is better to pass a constant reference of a string to method than a by value copy.

BOOL Find (const string&);

If you pass it by value a copy of the passed string is created on the stack, which might cause stack overflow (if the string is too long), and actually it is slow, because the copying of the object is also quite time consuming.

dave2k
November 20th, 2005, 09:45 AM
i tried to do the constant string like you said, but when callingw.Find("Play money")i get this: c:\Documents and Settings\david\Desktop\Test\Test.cpp(38): error C2664: 'Window::Find' : cannot convert parameter 1 from 'const char [11]' to 'std::string &'


why is this?

NoHero
November 20th, 2005, 09:53 AM
You are using a non constant reference, but a string literal (which is constant) cannot be casted to a non constant std::string object. Just change std::string & to const std::string & and it should work. (See my code above)

These are basic things regarding C++: I guess you should grab yourself a C++ book and start learning C++ from the beginning.

dave2k
November 20th, 2005, 12:12 PM
ok my code is nowbool Window::SetHook()
{
// Find the child RICHEDIT control and return its handle
HWND hwndCntrl = ::FindWindowEx(hwnd, NULL, "RICHEDIT", NULL);

if(!::IsWindow(hwndCntrl))
return false;

// Load HookProc.dll
hinstDLL = ::LoadLibrary((LPCTSTR) "HookProc.dll");
HOOKPROC hkprcSysMsg = (HOOKPROC)GetProcAddress(hinstDLL, "CallWndProc");

// Set the hook
DWORD ThreadIdCntrl = GetWindowThreadProcessId(hwndCntrl, 0);
HHOOK hh = ::SetWindowsHookEx(WH_CALLWNDPROC, hkprcSysMsg, hinstDLL, ThreadIdCntrl);

return true;
}In my hook procedure, i wrote MessageBeep(0); but it sn't working.

I have made a similar hook work with procedural code, so i dont know whats going wrong here.

NoHero
November 20th, 2005, 12:17 PM
Then check for return values of your API functions you call to see what's going wrong. This FAQ should help you with this task. (http://www.codeguru.com/forum/showthread.php?t=318721)

dave2k
November 20th, 2005, 12:18 PM
as i said i have used the same code procedurally, and worked fine

dave2k
November 20th, 2005, 12:23 PM
i tried a ReportLastError() also, and it came up with nothing!

dave2k
November 20th, 2005, 12:37 PM
i got t working in the end, the error says that the system cannot find the file specified. i assume it's talking about the dll, even though i have put a copy of the dll in my project, debug and release directories!!!

NoHero
November 20th, 2005, 12:39 PM
i tried a ReportLastError() also, and it came up with nothing!

So every API call above is returns successful? Have you tried to debug it, to find any other errors (not initialized variables, invalid variable values etc.)

dave2k
November 20th, 2005, 12:50 PM
here is the contents of my dll// HProc.cpp : Defines the entry point for the DLL application.

#include "stdafx.h"

__declspec(dllexport) LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam);

CWPSTRUCT *lpMsg;

LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam)
{
MessageBeep(0);
if(nCode < 0) return CallNextHookEx(0, nCode, wParam, lParam);
char* test = "dave";
lpMsg =(CWPSTRUCT *)lParam;
COPYDATASTRUCT cds = {0};

/* size of message */
cds.cbData = 200;
cds.dwData = 0;
cds.lpData = (char*)lpMsg->lParam;

HWND hGetLines = FindWindow(NULL, "GetLines");
//SendMessage(hGetLines, WM_COPYDATA, (WPARAM)lpMsg->hwnd, (LPARAM)&cds);

switch(lpMsg->message)
{
case EM_REPLACESEL:
MessageBeep(0);
SendMessage(hGetLines, WM_COPYDATA, (WPARAM)lpMsg->hwnd, (LPARAM)&cds);
//SendNotifyMessage(hGetLines, WM_COPYDATA, (WPARAM)lpMsg->hwnd, (LPARAM)&cds);
break;

default:
break;
}

return CallNextHookEx(0, nCode, wParam, lParam);
}

when i try the original code, it allways comes up with invalid hook procedure