GetWindowLongPtr sets Error to "Class already Exists" - c++

In my Windows API wrapper, I can choose to have a message box come up when there's an error. I have one that I can't really pin down though.
Here's my main function:
int main()
{
Window win; //create default window with default class (name changes each new instance)
return messageLoop(); //the familiar GetMessage() while loop, returns msg.wParam
}
This all works fine, but when I close my window (just tested via X button), I get the following message (this is what I get when I copy the message box):
---------------------------
Error
---------------------------
File: "G:\programming\v2\wwbasewindow.h"
Function: _fakeWndProc
Line: 61
Error Code: 1410
Error: Class already exists.
---------------------------
OK
---------------------------
Now it's crystal clear where this error is coming from, but not exactly why. Here's the _fakeWndProc function. The whole wrap (function, args) syntax checks GetLastError() after that function is called. This is why you don't see error checking.
LRESULT CALLBACK BaseWindow::_fakeWndProc (msgfillparams) //trick procedure (taken from someone's gui wrapper guide)
{
BaseWindow * destinationWindowPtr = 0; //for which window message goes to
//PROBLEM IN THE FOLLOWING LINE (gets a pointer to the window, set when it's created)
destinationWindowPtr = (BaseWindow *)wrap (GetWindowLongPtr, hwnd, GWLP_USERDATA);
if (msg == WM_COMMAND && lParam != 0) //if control message, set destination to that window
destinationWindowPtr = (BaseWindow *)wrap (GetWindowLongPtr, (hwin)lParam, GWLP_USERDATA);
if (destinationWindowPtr) //check if pointer is valid
return destinationWindowPtr->_WndProc (hwnd, msg, wParam, lParam); //call window's procedure
else
return wrap (DefWindowProc, hwnd, msg, wParam, lParam); //call default procedure
}
I'm just wondering why this call is (trying to create a class?) That aside, I tried checking the error codes from the time a WM_CLOSE message comes along. I output the code before the line, and after. This is what comes up:
Before: 0
After: 0
--->Before: 0
--->Before: 1410
After: 1410
Before: 1410
After: 1410
...
This puts the topping on my confusion, as this implies that the function calls SendMessage somewhere inside. But why wouldn't it do the same for any others?
The error itself doesn't make much of a difference, as the program ends right after, but I don't want it hanging around. How can I deal with it?
Note:
I just tried not calling PostQuitMessage (0); when WM_DESTROY came up, and created 2 windows. Both of them gave the same error when closing, so it's not necessarily the end of the program anyways.
Also, each one gave an error 1400 (Invalid window handle) too, but only when I didn't call PostQuitMessage. This error originated from the call to DefWindowProc in those windows' respective window procedures. Any ideas on that one either?
Edit:
Due to request, here is the code for wrap:
// pass along useful error information (useless constants within error function)
#define wrap(...) Wrap (__FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
// cstr == char *
// con == const
// sdword == int (signed dword)
// version if return value of API function is not void
template<typename TRet, typename... TArgs>
typename std::enable_if<!std::is_void<TRet>::value, TRet>::type
Wrap(con cstr file, const char * const func, con sdword line, TRet(*WINAPI api)(TArgs...), TArgs... args)
{
TRet result = api(std::forward<TArgs>(args)...); //call API function
if (GetLastError()) __wwError.set (GetLastError(), file, func, line); //set variables and create message box
return result; // pass back return value
}
// version if return value is void
template<typename... TArgs>
void Wrap(con cstr file, const char * const func, con sdword line, void(*WINAPI api)(TArgs...), TArgs... args)
{
api(std::forward<TArgs>(args)...);
if (GetLastError()) __wwError.set (GetLastError(), file, func, line);
}
I'm 100% sure this and __wwError.set() work though. All other functions wrapped with this give appropriate message boxes.

Your calls to GetLastError are simply incorrect. You cannot indiscriminately call GetLastError like that. You should only call it when the API call documentation says that it is valid to do so. Usually this will be if the API call reports failure.
The calls to DefWindowProc are a fine illustration of how this can go wrong. The documentation for DefWindowProc does not make any mention of a way for the function to report failure. And it makes no mention of calling GetLastError. Thus your calls to GetLastError should not be made and are returning undefined, meaningless values.
Since there is no single common mechanism for a Win32 function to report failure, your attempt to wrap all Win32 API calls with a single common error handling routine is doomed to failure.
What you need to do is to treat each API call on its own merits, and write error checking appropriate for that API call. Since you are using C++ I would recommend you make use of exceptions here. Write a function, ThrowLastWin32Error say, that you call whenever an API function reports failure. The implementation of ThrowLastWin32Error would call GetLastError and then call FormatMessage to obtain a textual description before throwing a suitably descriptive exception. You would use it like this:
if (!CallSomeWin32Function())
ThrowLastWin32Error();
But the main point is that you do need case-by-case checking of function success since different Win32 functions report failure in different ways.

Related

Can I launch the `GetLastError` in the first row of my function?

I know the GetLastError are to be called at once when error occured. I wrote the function:
void PrintErrorMsg() {
DWORD errCode = GetLastError();
LPTSTR msg = NULL;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, errCode, 0, (LPTSTR)&msg, 0, NULL);
wcerr << msg << endl;
HeapFree(GetProcessHeap(), 0, msg);
}
Now I use it in my code:
LPCTSTR boundaryName = L"BushmanBoundary";
HANDLE hBoundary = CreateBoundaryDescriptor(boundaryName, 0);
if (NULL == hBoundary) {
PrintErrorMsg();
}
So I called GetLastError in the first code row inside of the PrintErrorMsg function. Whether such variant of using is admissible?
That code is fine. No Windows API functions are called between CreateBoundaryDescriptor returning, and your call to GetLastError.
Functions executed by the calling thread set this value by calling the SetLastError function. You should call the GetLastError function immediately when a function's return value indicates that such a call will return useful data. That is because some functions call SetLastError with a zero when they succeed, wiping out the error code set by the most recently failed function.
Your code is fine because you are not calling a function that may call SetLastError() in between failure and your call to GetLastError() (e.g. Win32 API Calls.)
Keep in mind that the insertion operator may call SetLastError().
std::cout << "Win32 function failed with error: " << GetLastError() << std::endl;
I've been caught out by something like this in the past where GetLastError() would not return the correct error code because it had been set/reset by the insertion operator.
Yes, that's allowed. I've done something similar, except that I pass the error code in as an argument, but make the default value for the argument the result of GetLastError(), like this:
// in header file
void PrintErrorMsg( DWORD errCode = GetLastError() );
// in implementation file
void PrintErrorMsg( DWORD errCode )
{
// ...
}
It's more flexible, and worked very well for me.
I find that the best way to deal with these low-level details of the Win32 API (or any C style API), is to immediately hoist that C style API into C++ practices as soon as possible. One approach I used was to wrap C-style API calls in a macro that validates the return value and then extracts the appropriate error code into an exception if the return value indicated failure.
Chapter 1 of my book "The Direct3D Graphics Pipeline" outlines such an approach for COM HRESULT return values. A macro THR throws if the HRESULT indicates failure. In an HRESULT, the failure status and error code are contained in the same integral value, so the exception can be computed directly from the provided HRESULT. The macro decorates its argument with __FILE__ and __LINE__ before passing the value to be checked onto a helper function that checks for failure. If failure was detected, all the information is gathered up into an exception that is thrown. If the HRESULT indicates success, the HRESULT value is returned.
I also provided similar variants for Win32 API status with TWS. This does the necessary validation checks for the Win32 API (usually some version of comparing against FALSE or 0) and on failure immediately calls ::GetLastError() to obtain the error code for the exception.
In both cases, I attempt to use ::FormatMessage to obtain a meaningful error message string when building the exception value that will be thrown.
These macros are intended to be used in situations where you don't expect the API call to fail and failure is indeed truly exceptional.

Connecting callback to thread

I am calling a library function which also need a callback function as its only argument. It is time consuming function and the callback is called frequently to pass messages to the client (my application) to display. The problem is I want to copy the message and pass it onto the main thread for display but because it is callback function, I see no other way but to use globals to do that and that's what I am trying to avoid/make better.
The callback is static member function of my CTestDlg which alrady has m_hWnd member where I want to post the messages. However for the sake of callback I have yet defined another static g_hWnd member so my callback can access it and post message to it. This part doesn't look very nice to me but my callback routine is collecting messages wonderfully.
My callback function is the following
void CTestDlg::OnNotify (int code, const char * msg)
{
char * message = NULL; // to copy the message
message = new char[ strlen( msg) + 1 ]();
strcpy_s( message, strlen(msg) +1, msg );
PostMessageA( g_hWnd, ID_NOTIFY_MSG, code, (LPARAM) message );
}
I am running the library call in a separate thread and because it is callback to that function, it also runs in the same thread. Is there a better way to change hand in this callback function and pass the message to main thread or a particularly window to display?
If your callback is a static method, it has no access to instance data, so you must store your state data (the main window handle, in your case) in a static or global variable.
You can move the handle from a global variable to a static CTestDlg::s_hWnd variable.

How to return value from asynchronous function in dll

My dll has asynchronous function which starts a thread and returns immediately. It accepts handle of event object (type HANDLE) which the thread signals when it is done. This works fine but how can I return result from the function that it passed and no error occurred? A simple bool type will do.
I am thinking of using GetLastError() kind of call to get result of last function but I am not really sold on this way. I also looked at std::future and std::async but I am not sure if I can use that in dll function!? Another option I thought about is to use GetOverlappedResultbut that works usually with file i/o and I don't know if I can use this for a custom function that I have written.
Chad is right callback is safe and easy way to do it
// DLL:
__declspec(dllexport) void (*callback_function)(DWORD ret)=NULL;
DWORD _stdcall thread_function(LPVOID p)
{
// do something ...
if (callback_function) callback_function(some_return_value);
}
// DLL usage
DWORD return_value1=0;
bool done1=false;
void callback_function1(DWORD ret)
{
return_value1=ret;
done1=true;
}
void main()
{
callback_function=callback_function1; // set callbak function for DLL
done1=false; // invalidate return value
// here call you DLL function
for (;!done1;) Sleep(1); // wait for valid result ... also can add some timeout to avoid hang-ups
// now in return_value1 is the valid return value
}
also you can use waitforsingleobject instead
http://msdn.microsoft.com/en-us/library/windows/desktop/ms687032(v=vs.85).aspx

Multithreading with _beginthread and CreateThread

I try to write a Multithreading WIN32 Application in C++, but due to i get difficulties.
One of the Window Procedure creates a Thread, which manages the output of this window. If this Window Procedure receives a message (from the other Window Procedures), it should transmit it to their Thread. At the beginning i worked with the _beginthread(...) function, what doesn't work.
Then i tried it with the CreateThread(...) function, and it worked? What did i do wrong?
(My English isn't so good, i hope you understand my problem)
Code with CreateThread(...):
DWORD thHalloHandle; // global
HWND hwndHallo; // Hwnd of WndProc4
...
LRESULT APIENTRY WndProc4 (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static PARAMS params ;
switch (message)
{
case WM_CREATE: {
params.hwnd = hwnd ;
params.cyChar = HIWORD (GetDialogBaseUnits ()) ;
CreateThread(NULL, 0, thHallo, &params, 0, &thHalloHandle);
return 0 ;
}
...
case WM_SPACE: {
PostThreadMessage(thHalloHandle, WM_SPACE, 0, 0);
return 0;
}
...
}
Code with _beginthread(...):
...
case WM_CREATE: {
params.hwnd = hwnd ;
params.cyChar = HIWORD (GetDialogBaseUnits ()) ;
thHalloHandle = (DWORD)_beginthread (thHallo, 0, &params) ;
return 0;
}
...
case WM_SPACE: {
PostThreadMessage(thHalloHandle, WM_SPACE, 0, 0);
return 0;
}
...
thHallo for CreateThread:
DWORD WINAPI thHallo(void *pvoid)
{
static TCHAR *szMessage[] = { TEXT(...), ...};
// Some Declaration
pparams = (PPARAMS) pvoid;
while(!pparams->bKill)
{
MsgReturn = GetMessage(&msg, NULL, 0, 0);
hdc = GetDC(pparams->hwnd);
if(MsgReturn)
{
switch(msg.message)
{
// case....
}
}
}
return 0;
}
thHallo for _beginthread(...):
void thHallo(void *pvoid)
{
...
// The Same like for CreateThread
...
_endthread();
}
The _beginthread/ex() function is proving to be radically difficult to eliminate. It was necessary back in the previous century, VS6 was the last Visual Studio version that required it. It was a band-aid to allow the CRT to allocate thread-local state for internal CRT variables. Like the ones used for strtok() and gmtime(), CRT functions that maintain internal state. That state must be stored separately for each thread so that the use of, say, strtok() in one thread doesn't screw up the use of strtok() in another thread. It must be stored in thread-local state. _beginthread/ex() ensures that this state is allocated and cleaned-up again.
That has been worked on, necessarily so when Windows 2000 introduced the thread-pool. There is no possible way to get that internal CRT state initialized when your code gets called by a thread-pool thread. Quite an effort btw, the hardest problem they had to solve was to ensure that the thread-local state is automatically getting cleaned-up again when the thread stops running. Many a program has died on that going wrong, Apple's QuickTime is a particularly nasty source of these crashes.
So forget that _beginthread() ever existed, using CreateThread() is fine.
There's a serious problem with your use of PostThreadMessage(). You are used the wrong argument in your _beginthread() code which is why it didn't work. But there are bigger problems with it. The message that is posted can only ever be retrieved in your message loop. Which works fine, until it is no longer your message loop that is dispatching messages. That happens in many cases in a GUI app. Simple examples are using MessageBox(), DialogBox() or the user resizing the window. Modal code that works by Windows itself pumping the message loop.
A big problem is the message loop in that code knows beans about the messages you posted. They just fall in the bit-bucket and disappear without trace. The DispatchMessage() call inside that modal loop fails, the message you posted has a NULL window handle.
You must fix this by using PostMessage() instead. Which requires a window handle. You can use any window handle, the handle of your main window is a decent choice. Better yet, you can create a dedicated window, one that just isn't visible, with its own WndProc() that just handles these inter-thread messages. A very common choice. DispatchMessage() can now no longer fail, solves your bug as well.
Your call to CreateThread puts the thread ID into thHalloHandle. The call to _beginthread puts the thread handle into thHalloHandle.
Now, the thread ID is not the same as the thread handle. When you call PostThreadMessage you do need to supply a thread ID. You only do that for the CreateThread variant which I believe explains the problem.
Your code lacks error checking. Had you checked for errors on the call to PostThreadMessage you would have found that PostThreadMessage returned FALSE. Had you then gone on to call GetLastError that would have returned ERROR_INVALID_THREAD_ID. I do urge you to include proper error checking.
In order to address this you must first be more clear on the difference between thread ID and thread handle. You should give thHalloHandle a different name: thHalloThreadId perhaps. If you wish to use _beginthread you will have to call GetThreadId, passing the thread handle, to obtain the thread ID. Alternatively, use _beginthreadex which yields the thread ID, or indeed CreateThread.
Your problem is that you need a TID (Thread Identifier) to use PostThreadMessage.
_beginthread doesn't return a TID, it return a Thread Handle.
Solution is to use the GetThreadId function.
HANDLE hThread = (HANDLE)_beginthread (thHallo, 0, &params) ;
thHalloHandle = GetThreadId( hThread );
Better Code (see the documentation here)
HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, thHallo, &params, 0, &thHalloHandle ) ;

ESP error when sending window messages between threads

I have an Observer class and a Subscriber class.
For testing purposes, the observer creates a thread that generates fake messages and calls CServerCommandObserver::NotifySubscribers(), which looks like this:
void CServerCommandObserver::NotifySubscribers(const Command cmd, void const * const pData)
{
// Executed in worker thread //
for (Subscribers::const_iterator it = m_subscribers.begin(); it != m_subscribers.end(); ++it)
{
const CServerCommandSubscriber * pSubscriber = *it;
const HWND hWnd = pSubscriber->GetWindowHandle();
if (!IsWindow(hWnd)) { ASSERT(FALSE); continue; }
SendMessage(hWnd, WM_SERVERCOMMAND, cmd, reinterpret_cast<LPARAM>(pData));
}
}
The subscriber is a CDialog derived class, that also inherits from CServerCommandSubscriber.
In the derived class, I added a message map entry, that routes server commands to the subscriber class handler.
// Derived dialog class .cpp
ON_REGISTERED_MESSAGE(CServerCommandObserver::WM_SERVERCOMMAND, HandleServerCommand)
// Subscriber base class .cpp
void CServerCommandSubscriber::HandleServerCommand(const WPARAM wParam, const LPARAM lParam)
{
const Command cmd = static_cast<Command>(wParam);
switch (cmd)
{
case something:
OnSomething(SomethingData(lParam)); // Virtual method call
break;
case // ...
};
}
The problem is, that I see strange crashes in the HandleServerCommand() method:
It looks something like this:
Debug Error!
Program: c:\myprogram.exe
Module:
File: i386\chkesp.c
Line: 42
The value of ESP was not properly
saved across a function call. This is
usually the result of calling a
function declared with one calling
convention with a function pointer
declared with a different calling
convention.
I checked the function pointer that AfxBeginThread() wants to have:
typedef UINT (AFX_CDECL *AFX_THREADPROC)(LPVOID); // AFXWIN.H
static UINT AFX_CDECL MessageGeneratorThread(LPVOID pParam); // My thread function
To me, this looks compatible, isn't it?
I don't know, what else I have to look for. Any ideas?
I made another strange observation, that might be related:
In the NotifySubscribersmethod, I call IsWindow() to check if the window to which the handle points, exists. Apparently it does. But calling CWnd::FromHandlePermanent() returns a NULL pointer.
From afxmsg_.h:
// for Registered Windows messages
#define ON_REGISTERED_MESSAGE(nMessageVariable, memberFxn) \
{ 0xC000, 0, 0, 0, (UINT_PTR)(UINT*)(&nMessageVariable), \
/*implied 'AfxSig_lwl'*/ \
(AFX_PMSG)(AFX_PMSGW) \
(static_cast< LRESULT (AFX_MSG_CALL CWnd::*)(WPARAM, LPARAM) > \
(memberFxn)) },
So the signature is LRESULT ClassName::FunctionName(WPARAM, LPARAM), while yours is void ClassName::FunctionName(const WPARAM, const LPARAM). This should not compile, at least under VS2008 it doesn't.
What is your HandleServerCommand declaration in the CServerCommandSubscriber class (in the header file)?
To me, this looks compatible, isn't
it?
Syntactically it looks that way.
I don't know, what else I have to look
for. Any ideas?
Yes: I've had the same problem when compiling a plugin library with debug settings and used in a Release-compiled application.
Basically, the problem looks like a stack corruption.
Since you're running NotifySubscribers in a separate thread, consider using PostMessage (or PostThreadMessage) instead of SendMessage.
This may not be the actual cause of the crash, but the change should be made anyway (as you're switching threading contexts by using SendMessage with no guarding of the data whatsoever.
I eventually decided to do it without window messages and am now posting my workaround here. Maybe it will help someone else.
Instead of letting the observer post window messages to its subscribers, I let the observer put data into synchronized subscriber buffers. The dialog class subscriber uses a timer to periodically check its buffers and call the apropriate handlers if those aren't empty.
There are some disadvantages:
It's more coding effort because for each data type, a buffer member needs to be added to the subscriber.
It's also more space consuming, as the data exists for each subscriber and not just once during the SendMessage() call.
One also has to do the synchronization manually instead of relying on the observer thread being suspended while the messages are handled.
A - IMO - huge advantage is that it has better type-safety. One doesn't have to cast some lParam values into pointers depending on wParam's value. Because of this, I think this workaround is very acceptable if not even superior to my original approach.