![]() |
| | #1 |
| Registered User Join Date: Jun 2009
Posts: 5
| I'm new to this forum and fairly new to Windows programming as well. Anyway, I inherited some code from a previous engineer that works fine in 32-bit, but fails in 64-bit. In 64-bit, CreateWindowEx() fails, and GetLastError() returns code 1413, which is "invalid index". I haven't been able to find anything online mentioning any problem with CreateWindowEx() in 64-bit environments. Any help is appreciated: Code: //call this function to creat the actual window.
bool CPrintWindow::Create(char* szWindowName,
DWORD dwStyle,
const RECT& rect,
HWND hParentWnd,
HINSTANCE hInst,
char* szClassName,
bool registerClass)
{
//TraceFunc("CPrintWindow::Create()");
if(registerClass) //local register requested
{
if(!szClassName) szClassName = "DefaultCPrintWindowName"; //if no name specified
m_wndClass.lpszClassName = szClassName;
m_wndClass.hInstance = hInst;
if(!GetClassInfo(hInst, szClassName, &m_wndClass))
{
//not yet registered, must register
m_classAtom = RegisterClass(&m_wndClass);
}
}
else if(!szClassName)
return false; //error, must have a WNDCLASS
m_hInstance = hInst;
//set the static variable to point to this instance so that
//the message loop can find it when it starts up
m_lastCPrintWindow = this;
m_hWndMain = CreateWindowEx(m_exStyle,
szClassName,
szWindowName,
dwStyle,
rect.left,
rect.top,
rect.right - rect.left,
rect.bottom - rect.top,
hParentWnd,
NULL,
m_hInstance,
NULL);
if(m_hWndMain)
return true; //success
//Failed! - Give a detailed error message to show what went wrong
char szMessage[256];
DWORD result = GetLastError();
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, result, 0, szMessage, 256, 0);
MessageBox(NULL, szMessage, "Error", MB_OK);
return false;
}
Thanks, Kenneth |
| domokato is offline | |
| | #2 |
| Hat seller extraordinaire Join Date: Apr 2008
Posts: 159
| Do you have any calls to GetWindowLongPtr/GetClassLongPtr or their Set equivalents in the relevant WndProc for WM_NCCREATE or WM_CREATE? That'd be my bet. You should also check that RegisterClass is succeeding, though that would probably give a different error. The use of FormatMessage seems a bit dubious too, FORMAT_MESSAGE_IGNORE_INSERTS should also be passed so that it doesn't try and do parameter substitution in messages that require it. FormatMessage will fail if you pass NULL/0 for the last parameter and the string contains inserts, causing your MessageBox to potentally display garbage. |
| adeyblue is offline | |
| | #3 |
| Registered User Join Date: Jun 2009
Posts: 5
| Here's the wndproc: Code: static __declspec(dllexport)
LRESULT CALLBACK WndProcedure(HWND hWnd, UINT wMessage,
WPARAM wParam, LPARAM lParam)
{
//retrieve the pointer to the class stored in the HWND
#ifdef _WIN64
CPrintWindow* pWnd = (CPrintWindow*)GetWindowLongPtr(hWnd, 0);
#else
CPrintWindow* pWnd = (CPrintWindow*)GetWindowLong(hWnd, 0);
#endif
if (pWnd == NULL) //this must be the first time here
{
//store the class instance
#ifdef _WIN64
SetWindowLongPtr(hWnd, 0, (ULONG_PTR)m_lastCPrintWindow);
//Set pWnd to point to the class instance
pWnd = (CPrintWindow*)GetWindowLongPtr(hWnd, 0);
#else
SetWindowLong(hWnd, 0, (LONG)m_lastCPrintWindow);
//Set pWnd to point to the class instance
pWnd = (CPrintWindow*)GetWindowLong(hWnd, 0);
#endif
}
return pWnd->OnMainMessage(hWnd, wMessage, wParam, lParam);
}
Code: //this is the main message loop.
//handles most used messages here
LRESULT CPrintWindow::OnMainMessage(HWND hWnd, UINT wMessage,
WPARAM wParam, LPARAM lParam)
{
//TraceFunc("CPrintWindow::OnMainMessage()");
LRESULT result = 0;
m_hWndMain = hWnd;
if (wMessage == WM_DESTROY)
{
result = 0;
SendMessage(m_hWndMain, WM_QUIT, 0, 0);
}
//first see if this message is handled by any other handler
if (OnMessage(hWnd, wMessage, wParam, lParam, &result))
return result;
//see if the message is one of the basic handled ones,
//and call the correct handler if it is
switch (wMessage)
{
case WM_PAINT:
{
PAINTSTRUCT psPaint;
HDC hDC = BeginPaint(hWnd, &psPaint);
OnPaint(hDC, &psPaint);
EndPaint(hWnd, &psPaint);
}
break;
case WM_ERASEBKGND:
{
HDC hDC = (HDC) wParam;
if (OnEraseBkGnd(hDC))
return true; //handled, so return
else
return DefWindowProc(hWnd, wMessage, wParam, lParam);
}
//break;
case WM_COMMAND:
if(!OnCommand(wParam, lParam))
return DefWindowProc(hWnd, wMessage, wParam, lParam); //return if handled
break;
default:
//seems like this message was not processed by any handler, so
//let's send it to the default handler
return DefWindowProc(hWnd, wMessage, wParam, lParam);
//break;
}
return 0;
}
|
| domokato is offline | |
| | #4 |
| Registered User Join Date: Jun 2009
Posts: 5
| Okay, I just traced through WndProcedure() and found that this line, Code: CPrintWindow* pWnd = (CPrintWindow*)GetWindowLongPtr(hWnd, 0); Code: pWnd = (CPrintWindow*)GetWindowLongPtr(hWnd, 0); Intellisense: Code: hWnd = 0x00000000012e0114 {unused=??? }
|
| domokato is offline | |
| | #5 |
| Hat seller extraordinaire Join Date: Apr 2008
Posts: 159
| What is m_wndClass.cbWndExtra set to? It should be sizeof(CPrintWindow*) or at least greater than or equal to 4 or 8 if it's in an #ifdef _WIN64 block. |
| adeyblue is offline | |
| | #6 |
| Registered User Join Date: Jun 2009
Posts: 5
| Yes, thank you. It used to be 4, actually, but I changed it to sizeof(CPrintWindow *) and now the window displays. However, the contents of the window doesn't show up. It is painted using bitblt(). You can see the handling for WM_PAINT in OnMainMessage() above. BeginPaint() results in: Intellisense: Code: hDC = 0xfffffffff9010287 {unused=??? }
Code: psPaint = {hdc=0xfffffffff9010287 fErase=0 rcPaint={...} ...}
Code: void CPrintWindow::OnPaint(HDC hDC, PAINTSTRUCT* pPS)
{
//TraceFunc("CPrintWindow::OnPaint()");
RECT rectBmUpdate;
IntersectRect(&rectBmUpdate, &m_rectBitmap, &pPS->rcPaint);
if(!IsRectEmpty(&rectBmUpdate))
{
BitBlt(hDC,
rectBmUpdate.left,
rectBmUpdate.top,
rectBmUpdate.right - rectBmUpdate.left,
rectBmUpdate.bottom - rectBmUpdate.top,
m_hMemDC,
rectBmUpdate.left - PAGE_BORDER,
rectBmUpdate.top - PAGE_BORDER,
SRCCOPY);
}
}
Thanks, Kenneth |
| domokato is offline | |
| | #7 |
| Registered User Join Date: Jun 2009
Posts: 5
| Hi, I found this thread: how splwow64 works - Windows Device Drivers which says that a printer driver plugin running in the context of splwow64 (which mine is) should not call CreateDC() because it will fail. My code calls CreateCompatibleDC(), and this does indeed return null. This is probably related to the problem described in my previous post. Perhaps I have to use an alternative to HDCs? Is there an alternative? Thanks, Kenneth |
| domokato is offline | |
| | #8 |
| Hat seller extraordinaire Join Date: Apr 2008
Posts: 159
| There isn't any alternative as far as GDI is concerned, though what you can do about it I've no idea. I tend to stay away from all things printer related. Posting what GetLastError() returns after CreateCompatibleDC fails might help any other potential helpers provide a course of action. |
| adeyblue is offline | |
![]() |
| Thread Tools | |
| Display Modes | |
|
Similar Threads | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| A few questions about 64 bit and Windows... | yaya | Tech Board | 9 | 08-28-2008 08:49 AM |
| [Tutorial] Implementing the Advanced Encryption Standard | KONI | C Programming | 16 | 11-23-2007 01:48 PM |
| File IO | Jack1982 | C++ Programming | 9 | 10-15-2007 01:14 AM |
| bit patterns of negtive numbers? | chunlee | C Programming | 4 | 11-08-2004 08:20 AM |
| Array of boolean | DMaxJ | C++ Programming | 11 | 10-25-2001 11:45 PM |