//-------------------------------------------------------------------------- void VeWindows::_DestoryWindow(Window* pkWindow) { WindowData* pkData = (WindowData*)(VeRefObject*)pkWindow->m_spDriverData; if(pkData) { _EnableIME(pkWindow); ReleaseDC(pkData->m_hWnd, pkData->m_hHdc); if(pkData->m_bCreated) { DestroyWindow(pkData->m_hWnd); } else { if(pkData->m_pfuncWndProc != NULL) { # ifdef GWLP_WNDPROC SetWindowLongPtr(pkData->m_hWnd, GWLP_WNDPROC, (LONG_PTR)pkData->m_pfuncWndProc); # else SetWindowLong(pkData->m_hWnd, GWL_WNDPROC, (LONG_PTR)pkData->m_pfuncWndProc); # endif } } pkWindow->m_spDriverData = NULL; } WNDCLASSEXA kClass; if(GetClassInfoExA(m_kParams.m_hInstance, m_kParams.m_pcAppName, &kClass)) { UnregisterClass(m_kParams.m_pcAppName, m_kParams.m_hInstance); } }
static void test_button_class(void) { static const WCHAR testW[] = {'t','e','s','t',0}; WNDCLASSEXW exW, ex2W; WNDCLASSEXA exA; char buffA[100]; WCHAR *nameW; HWND hwnd; BOOL ret; int len; ret = GetClassInfoExA(NULL, WC_BUTTONA, &exA); ok(ret, "got %d\n", ret); todo_wine ok(IS_WNDPROC_HANDLE(exA.lpfnWndProc), "got %p\n", exA.lpfnWndProc); ret = GetClassInfoExW(NULL, WC_BUTTONW, &exW); ok(ret, "got %d\n", ret); ok(!IS_WNDPROC_HANDLE(exW.lpfnWndProc), "got %p\n", exW.lpfnWndProc); /* check that versioned class is also accessible */ nameW = get_versioned_classname(WC_BUTTONW); ok(lstrcmpW(nameW, WC_BUTTONW), "got %s\n", wine_dbgstr_w(nameW)); ret = GetClassInfoExW(NULL, nameW, &ex2W); todo_wine { ok(ret, "got %d\n", ret); ok(ex2W.lpfnWndProc == exW.lpfnWndProc, "got %p, %p\n", exW.lpfnWndProc, ex2W.lpfnWndProc); } /* Check reported class name */ hwnd = create_button(BS_CHECKBOX, NULL); len = GetClassNameA(hwnd, buffA, sizeof(buffA)); ok(len == strlen(buffA), "got %d\n", len); ok(!strcmp(buffA, "Button"), "got %s\n", buffA); len = RealGetWindowClassA(hwnd, buffA, sizeof(buffA)); ok(len == strlen(buffA), "got %d\n", len); ok(!strcmp(buffA, "Button"), "got %s\n", buffA); DestroyWindow(hwnd); /* explicitely create with versioned class name */ hwnd = CreateWindowExW(0, nameW, testW, BS_CHECKBOX, 0, 0, 50, 14, NULL, 0, 0, NULL); todo_wine ok(hwnd != NULL, "failed to create a window %s\n", wine_dbgstr_w(nameW)); if (hwnd) { len = GetClassNameA(hwnd, buffA, sizeof(buffA)); ok(len == strlen(buffA), "got %d\n", len); ok(!strcmp(buffA, "Button"), "got %s\n", buffA); len = RealGetWindowClassA(hwnd, buffA, sizeof(buffA)); ok(len == strlen(buffA), "got %d\n", len); ok(!strcmp(buffA, "Button"), "got %s\n", buffA); DestroyWindow(hwnd); } }
static void register_subclass(void) { WNDCLASSEXA cls; cls.cbSize = sizeof(WNDCLASSEXA); GetClassInfoExA(NULL, STATUSCLASSNAMEA, &cls); g_status_wndproc = cls.lpfnWndProc; cls.lpfnWndProc = create_test_wndproc; cls.lpszClassName = SUBCLASS_NAME; cls.hInstance = NULL; ok(RegisterClassExA(&cls), "RegisterClassEx failed\n"); }
////////// // // Creates the message window used for communicating actions // ////// void iVjr_init_createMessageWindow(void) { ATOM atom; WNDCLASSEXA classa; ////////// // Register the classes if need be ////// while (1) { if (!GetClassInfoExA(ghInstance, (cs8*)cgcMessageWindowClass, &classa)) { // Initialize memset(&classa, 0, sizeof(classa)); // Populate classa.cbSize = sizeof(WNDCLASSEXA); classa.hInstance = ghInstance; classa.lpszClassName = (cs8*)cgcMessageWindowClass; classa.lpfnWndProc = &iWindow_wndProcMessage; // Register atom = RegisterClassExA(&classa); if (!atom) break; } ////////// // Create the message window ////// ghwndMsg = CreateWindowA((cs8*)cgcMessageWindowClass, (cs8*)cgcMessageWindowClass, 0, 0, 0, 0, 0, HWND_MESSAGE, null0, ghInstance, 0); if (ghwndMsg) { // Create a timer for the message window firing 20x per second SetTimer(ghwndMsg, 0, 50, null0); // Read events CreateThread(NULL, 0, &iReadEvents_messageWindow, 0, 0, 0); return; } break; } // We should never get here MessageBoxA(null0, "Error creating Visual FreePro Jr's message window.", "VJr - Fatal Error", MB_OK); }
/*********************************************************************** * AtlModuleRegisterWndClassInfoA [ATL.@] * * See AtlModuleRegisterWndClassInfoW. */ ATOM WINAPI AtlModuleRegisterWndClassInfoA(_ATL_MODULEA *pm, _ATL_WNDCLASSINFOA *wci, WNDPROC *pProc) { ATOM atom; FIXME("%p %p %p semi-stub\n", pm, wci, pProc); atom = wci->m_atom; if (!atom) { WNDCLASSEXA wc; TRACE("wci->m_wc.lpszClassName = %s\n", wci->m_wc.lpszClassName); if (wci->m_lpszOrigName) FIXME( "subclassing %s not implemented\n", debugstr_a(wci->m_lpszOrigName)); if (!wci->m_wc.lpszClassName) { snprintf(wci->m_szAutoName, sizeof(wci->m_szAutoName), "ATL%08lx", (UINT_PTR)wci); TRACE("auto-generated class name %s\n", wci->m_szAutoName); wci->m_wc.lpszClassName = wci->m_szAutoName; } atom = GetClassInfoExA(pm->m_hInst, wci->m_wc.lpszClassName, &wc); if (!atom) { wci->m_wc.hInstance = pm->m_hInst; wci->m_wc.hCursor = LoadCursorA( wci->m_bSystemCursor ? NULL : pm->m_hInst, wci->m_lpszCursorID ); atom = RegisterClassExA(&wci->m_wc); } wci->pWndProc = wci->m_wc.lpfnWndProc; wci->m_atom = atom; } if (wci->m_lpszOrigName) *pProc = wci->pWndProc; TRACE("returning 0x%04x\n", atom); return atom; }
HOOKFUNC HWND WINAPI MyCreateWindowExA(DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName, DWORD dwStyle, int X, int Y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam) { debuglog(LCF_WINDOW|LCF_TODO, __FUNCTION__ "(%d,%d,%d,%d,0x%X,0x%X) called.\n", X,Y,nWidth,nHeight,dwStyle,dwExStyle); createWindowDepth++; //if(tasflags.forceWindowed && X == 0 && Y == 0 && nWidth > 640 && nHeight > 480) //{ // // check for exact matches with the screen size // // (because this might be a fake-fullscreen window) // if(nWidth == GetSystemMetrics(SM_CXSCREEN) && nHeight == GetSystemMetrics(SM_CYSCREEN)) // { // nWidth = 640; // nHeight = 480; // dwStyle &= ~WS_POPUP; // dwStyle |= WS_CAPTION; // } //} HWND oldGamehwnd = gamehwnd; ThreadLocalStuff& curtls = tls; curtls.callerisuntrusted++; curtls.treatDLLLoadsAsClient++; HWND hwnd = CreateWindowExA(dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam); HOOKFUNC BOOL WINAPI MySetWindowTextA(HWND hWnd, LPCSTR lpString); MySetWindowTextA(hwnd, lpWindowName); curtls.treatDLLLoadsAsClient--; curtls.callerisuntrusted--; debuglog(LCF_WINDOW, __FUNCTION__ " made hwnd = 0x%X.\n", hwnd); #ifdef EMULATE_MESSAGE_QUEUES if(hwnd) { MessageQueue& mq = curtls.messageQueue; // if(mq.attachedWindows.empty()) // mq.attachedWindows.insert((HWND)NULL); // so PostMessage with a NULL HWND knows to post to the current thread mq.attachedWindows.push_back(hwnd); } #endif createWindowDepth--; if(hwnd && createWindowDepth == 0) { if(!oldGamehwnd) { curtls.createdFirstWindow = true; gamehwnd = hwnd; } WNDPROC oldProc = (WNDPROC)MyGetWindowLongA(hwnd, GWL_WNDPROC); if(!oldProc) { WNDCLASSEXA cls = { sizeof(WNDCLASSEXA) }; GetClassInfoExA(hInstance, lpClassName, &cls); if(cls.lpfnWndProc) { oldProc = cls.lpfnWndProc; debuglog(LCF_WINDOW|LCF_TODO, "had to retrieve wndproc from wndclass (\"%s\") for some reason...\n", lpClassName); } } debuglog(LCF_WINDOW, "oldProc[0x%X] = 0x%X\n", hwnd, oldProc); hwndToOrigHandler[hwnd] = oldProc; SetWindowLongA(hwnd, GWL_WNDPROC, (LONG)MyWndProcA); cmdprintf("HWND: %d", hwnd); if(tasflags.windowActivateFlags & 2) { // hmm, I'm getting desyncs all of a sudden... // the wintaser window flickers every time it happens // but I don't know what could be causing that. // well, maybe it's happening less now for some reason, // but it's something to watch for (possible bugs here) // tasflags.windowActivateFlags ^= 2; // ShowWindow(hwnd, TRUE); SetForegroundWindow(hwnd); //SetActiveWindow(hwnd); //SetFocus(hwnd); SetWindowPos(hwnd, HWND_TOPMOST, 0,0,0,0, SWP_NOMOVE|SWP_NOSIZE); // tasflags.windowActivateFlags ^= 2; } else { SetWindowPos(hwnd, HWND_NOTOPMOST, 0,0,0,0, SWP_NOMOVE|SWP_NOSIZE); } SetActiveWindow(hwnd); // FIXME TEMP maybe need to hook SetActiveWindow / SetForegroundWindow etc instead DispatchMessageInternal(hwnd, WM_ACTIVATE, WA_ACTIVE, (LPARAM)hwnd); DispatchMessageInternal(hwnd, WM_SETFOCUS, 0, 0); /*WINDOWPOS pos = { hwnd,//HWND hwnd; hWndParent,//HWND hwndInsertAfter; X,//int x; Y,//int y; nWidth,//int cx; nHeight,//int cy; SWP_NOREDRAW|SWP_NOACTIVATE|SWP_FRAMECHANGED,//UINT flags; };*/ //DispatchMessageInternal(hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)&pos); CREATESTRUCTA create = { lpParam,//LPVOID lpCreateParams; hInstance,//HINSTANCE hInstance; hMenu,//HMENU hMenu; hWndParent,//HWND hwndParent; nHeight,//int cy; nWidth,//int cx; Y,//int y; X,//int x; dwStyle,//LONG style; lpWindowName,//LPCTSTR lpszName; lpClassName,//LPCTSTR lpszClass; dwExStyle,//DWORD dwExStyle; }; DispatchMessageInternal(hwnd, WM_CREATE, 0, (LPARAM)&create); } return hwnd; }
/* * ::createGlInitContext */ BOOL createGlInitContext(GlInitContext *outCtx) { HINSTANCE hInst = GetModuleHandle(NULL); GLuint pixelFormat = 0; PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, PFD_TYPE_RGBA, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, PFD_MAIN_PLANE, 0, 0, 0, 0 }; WNDCLASSEXA wndClass; if (outCtx == NULL) { return FALSE; } outCtx->hWnd = NULL; outCtx->hDC = NULL; outCtx->hRC = NULL; /* Register window class, if not yet available. */ if (!GetClassInfoExA(hInst, INITCTX_WNDCLASS_NAME, &wndClass)) { ZeroMemory(&wndClass, sizeof(WNDCLASSEX)); wndClass.cbSize = sizeof(WNDCLASSEX); wndClass.style = CS_CLASSDC; wndClass.lpfnWndProc = DefWindowProc; wndClass.hInstance = hInst; wndClass.lpszClassName = INITCTX_WNDCLASS_NAME; if (!RegisterClassExA(&wndClass)) { dbgPrint(DBGLVL_ERROR, "Registering window class for GL detours initialisation " "failed: %u\n", GetLastError()); return FALSE; } } /* Create window. */ if ((outCtx->hWnd = CreateWindowExA(WS_EX_APPWINDOW, INITCTX_WNDCLASS_NAME, "", WS_POPUP, 0, 0, 1, 1, NULL, NULL, hInst, NULL)) == NULL) { dbgPrint(DBGLVL_ERROR, "Creating window for GL detours initialisation failed:\n", GetLastError()); releaseGlInitContext(outCtx); return FALSE; } /* Create OpenGL context. */ outCtx->hDC = GetDC(outCtx->hWnd); if ((pixelFormat = ChoosePixelFormat(outCtx->hDC, &pfd)) == 0) { dbgPrint(DBGLVL_ERROR, "ChoosePixelFormat failed: %u\n", GetLastError()); releaseGlInitContext(outCtx); return FALSE; } if (!SetPixelFormat(outCtx->hDC, pixelFormat, &pfd)) { dbgPrint(DBGLVL_ERROR, "SetPixelFormat failed: %u\n", GetLastError()); releaseGlInitContext(outCtx); return FALSE; } if ((outCtx->hRC = wglCreateContext(outCtx->hDC)) == NULL) { dbgPrint(DBGLVL_ERROR, "wglCreateContext failed: %u\n", GetLastError()); releaseGlInitContext(outCtx); return FALSE; } if (!wglMakeCurrent(outCtx->hDC, outCtx->hRC)) { dbgPrint(DBGLVL_ERROR, "wglMakeCurrent failed: %u\n", GetLastError()); releaseGlInitContext(outCtx); return FALSE; } return TRUE; }
// Если (anFromShowWindow != -1), значит функу зовут из ShowWindow void OnGuiWindowAttached(HWND hWindow, HMENU hMenu, LPCSTR asClassA, LPCWSTR asClassW, DWORD anStyle, DWORD anStyleEx, BOOL abStyleHidden, int anFromShowWindow/*=-1*/) { DWORD nCurStyle = (DWORD)user->getWindowLongPtrW(hWindow, GWL_STYLE); DWORD nCurStyleEx = (DWORD)user->getWindowLongPtrW(hWindow, GWL_EXSTYLE); user->allowSetForegroundWindow(ASFW_ANY); // VLC создает несколько "подходящих" окон, но ShowWindow зовет // только для одного из них. Поэтому фактический аттач делаем // только в том случае, если окно "видимое" if ((!(nCurStyle & WS_VISIBLE)) && (anFromShowWindow <= SW_HIDE)) { // Значит потом, из ShowWindow return; } ghAttachGuiClient = hWindow; gnAttachGuiClientThreadId = user->getWindowThreadProcessId(hWindow, NULL); gbForceShowGuiClient = TRUE; gbAttachGuiClient = FALSE; // Только одно окно приложения. Пока? #if 0 // Для WS_CHILDWINDOW меню нельзя указать при создании окна if (!hMenu && !ghAttachGuiClientMenu && (asClassA || asClassW)) { BOOL lbRcClass; WNDCLASSEXA wca = {sizeof(WNDCLASSEXA)}; WNDCLASSEXW wcw = {sizeof(WNDCLASSEXW)}; if (asClassA) { lbRcClass = GetClassInfoExA(GetModuleHandle(NULL), asClassA, &wca); if (lbRcClass) ghAttachGuiClientMenu = LoadMenuA(wca.hInstance, wca.lpszMenuName); } else { lbRcClass = GetClassInfoExW(GetModuleHandle(NULL), asClassW, &wcw); if (lbRcClass) ghAttachGuiClientMenu = LoadMenuW(wca.hInstance, wcw.lpszMenuName); } hMenu = ghAttachGuiClientMenu; } if (hMenu) { // Для WS_CHILDWINDOW - не работает SetMenu(hWindow, hMenu); HMENU hSys = GetSystemMenu(hWindow, FALSE); TODO("Это в принципе прокатывает, но нужно транслировать WM_SYSCOMMAND -> WM_COMMAND, соответственно, перехватывать WndProc, или хук ставить"); if (hSys) { TODO("Хотя, хорошо бы не все в Popup засоывать, а извлечь ChildPopups из hMenu"); InsertMenu(hSys, 0, MF_BYPOSITION|MF_POPUP, (UINT_PTR)hMenu, L"Window menu"); InsertMenu(hSys, 1, MF_BYPOSITION|MF_SEPARATOR, NULL, NULL); } } #endif DWORD nSize = sizeof(CESERVER_REQ_HDR)+sizeof(CESERVER_REQ_ATTACHGUIAPP); CESERVER_REQ *pIn = ExecuteNewCmd(CECMD_ATTACHGUIAPP, nSize); gnAttachGuiClientFlags = agaf_Success; // С приложенями .Net - приходится работать как с WS_CHILD, // иначе в них "не нажимаются" тулбары и меню if (IsDotNetWindow(hWindow)) { gnAttachGuiClientFlags |= (agaf_DotNet|agaf_WS_CHILD); } // Если в окне нет меню - работаем с ним как с WS_CHILD // так не возникает проблем с активацией и т.д. else if (user->getMenu(hWindow) == NULL) { if (IsQtWindow(asClassA, asClassW)) gnAttachGuiClientFlags |= (agaf_NoMenu|agaf_QtWindow|agaf_WS_CHILD); else gnAttachGuiClientFlags |= (agaf_NoMenu|agaf_WS_CHILD); } pIn->AttachGuiApp.nFlags = gnAttachGuiClientFlags; pIn->AttachGuiApp.nPID = GetCurrentProcessId(); pIn->AttachGuiApp.hAppWindow = hWindow; pIn->AttachGuiApp.Styles.nStyle = nCurStyle; // стили могли измениться после создания окна, pIn->AttachGuiApp.Styles.nStyleEx = nCurStyleEx; // поэтому получим актуальные user->getWindowRect(hWindow, &pIn->AttachGuiApp.rcWindow); GetModuleFileName(NULL, pIn->AttachGuiApp.sAppFilePathName, countof(pIn->AttachGuiApp.sAppFilePathName)); pIn->AttachGuiApp.hkl = (DWORD)(LONG)(LONG_PTR)GetKeyboardLayout(0); wchar_t szGuiPipeName[128]; msprintf(szGuiPipeName, countof(szGuiPipeName), CEGUIPIPENAME, L".", (DWORD)ghConEmuWnd); // AttachThreadInput DWORD nConEmuTID = user->getWindowThreadProcessId(ghConEmuWnd, NULL); DWORD nTID = GetCurrentThreadId(); _ASSERTEX(nTID==gnHookMainThreadId || nTID==gnAttachGuiClientThreadId); BOOL bAttachRc = user->attachThreadInput(nTID, nConEmuTID, TRUE); DWORD nAttachErr = GetLastError(); UNREFERENCED_PARAMETER(bAttachRc); UNREFERENCED_PARAMETER(nAttachErr); HWND hPreFocus = user->getFocus(); CESERVER_REQ* pOut = ExecuteCmd(szGuiPipeName, pIn, 0/*Default timeout*/, NULL); ExecuteFreeResult(pIn); // abStyleHidden == TRUE, если окно при создании указало флаг WS_VISIBLE (т.е. не собиралось звать ShowWindow) if (pOut) { if (pOut->hdr.cbSize > sizeof(CESERVER_REQ_HDR)) { _ASSERTE((pOut->AttachGuiApp.nFlags & agaf_Success) == agaf_Success); BOOL lbRc = FALSE; _ASSERTE(pOut->AttachGuiApp.hConEmuBack && pOut->AttachGuiApp.hConEmuDc && (HWND)pOut->AttachGuiApp.hConEmuDc!=(HWND)pOut->AttachGuiApp.hConEmuBack); _ASSERTE((ghConEmuWndBack==NULL) || (pOut->AttachGuiApp.hConEmuBack==ghConEmuWndBack)); _ASSERTE(ghConEmuWnd && (ghConEmuWnd==pOut->AttachGuiApp.hConEmuWnd)); ghConEmuWnd = pOut->AttachGuiApp.hConEmuWnd; SetConEmuHkWindows(pOut->AttachGuiApp.hConEmuDc, pOut->AttachGuiApp.hConEmuBack); //gbGuiClientHideCaption = pOut->AttachGuiApp.bHideCaption; gGuiClientStyles = pOut->AttachGuiApp.Styles; #ifdef _DEBUG HWND hFocus = user->getFocus(); DWORD nFocusPID = 0; if (hFocus) { user->getWindowThreadProcessId(hFocus, &nFocusPID); DWORD nConEmuPID = 0; user->getWindowThreadProcessId(ghConEmuWnd, &nConEmuPID); if (nFocusPID != GetCurrentProcessId() && nFocusPID != nConEmuPID) { _ASSERTE(hFocus==NULL || (nFocusPID==GetCurrentProcessId() || nFocusPID == nConEmuPID)); hFocus = NULL; } } #endif if (pOut->AttachGuiApp.hkl) { LONG_PTR hkl = (LONG_PTR)(LONG)pOut->AttachGuiApp.hkl; lbRc = ActivateKeyboardLayout((HKL)hkl, KLF_SETFORPROCESS) != NULL; UNREFERENCED_PARAMETER(lbRc); } //grcAttachGuiClientPos = pOut->AttachGuiApp.rcWindow; ReplaceGuiAppWindow(abStyleHidden); //if (hPreFocus) //{ // user->setFocus(hPreFocus); //} UINT nMsgID = user->registerWindowMessageW(CONEMUMSG_RESTORECHILDFOCUS); user->postMessageW(ghConEmuWndBack, nMsgID, 0,0); //// !!! OnSetForegroundWindow не подходит - он дергает Cmd. ////user->setForegroundWindow(ghConEmuWnd); //#if 0 //wchar_t szClass[64] = {}; user->getClassNameW(hFocus, szClass, countof(szClass)); //MessageBox(NULL, szClass, L"WasFocused", MB_SYSTEMMODAL); //#endif ////if (!(nCurStyle & WS_CHILDWINDOW)) //{ // // Если ставить WS_CHILD - пропадет меню! // //nCurStyle = (nCurStyle | WS_CHILDWINDOW|WS_TABSTOP); // & ~(WS_THICKFRAME/*|WS_CAPTION|WS_MINIMIZEBOX|WS_MAXIMIZEBOX*/); // //user->setWindowLongPtrW(hWindow, GWL_STYLE, nCurStyle); // if (gnAttachGuiClientFlags & agaf_DotNet) // { // } // else // { // SetParent(hWindow, ghConEmuWndBack); // } //} // //RECT rcGui = grcAttachGuiClientPos = pOut->AttachGuiApp.rcWindow; //if (user->setWindowPos(hWindow, HWND_TOP, rcGui.left,rcGui.top, rcGui.right-rcGui.left, rcGui.bottom-rcGui.top, // SWP_DRAWFRAME | /*SWP_FRAMECHANGED |*/ (abStyleHidden ? SWP_SHOWWINDOW : 0))) //{ // if (abStyleHidden) // abStyleHidden = FALSE; //} // //// !!! OnSetForegroundWindow не подходит - он дергает Cmd. //user->setForegroundWindow(ghConEmuWnd); ////if (hFocus) ////SetFocus(hFocus ? hFocus : hWindow); // hFocus==NULL, эффекта нет ////OnSetForegroundWindow(hWindow); ////user->postMessage(ghConEmuWnd, WM_NCACTIVATE, TRUE, 0); ////user->postMessage(ghConEmuWnd, WM_NCPAINT, 0, 0); //user->postMessage(hWindow, WM_NCPAINT, 0, 0); } ExecuteFreeResult(pOut); } if (abStyleHidden) { user->showWindow(hWindow, SW_SHOW); } }
HWND WINAPI User32CreateWindowEx(DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam, DWORD dwFlags) { LARGE_STRING WindowName; LARGE_STRING lstrClassName, *plstrClassName; UNICODE_STRING ClassName; WNDCLASSEXA wceA; WNDCLASSEXW wceW; HMODULE hLibModule = NULL; DWORD save_error; BOOL Unicode, ClassFound = FALSE; HWND Handle = NULL; #if 0 DbgPrint("[window] User32CreateWindowEx style %d, exstyle %d, parent %d\n", dwStyle, dwExStyle, hWndParent); #endif if (!RegisterDefaultClasses) { TRACE("RegisterSystemControls\n"); RegisterSystemControls(); } Unicode = !(dwFlags & NUCWE_ANSI); if (IS_ATOM(lpClassName)) { plstrClassName = (PVOID)lpClassName; } else { if(Unicode) RtlInitUnicodeString(&ClassName, (PCWSTR)lpClassName); else { if (!RtlCreateUnicodeStringFromAsciiz(&ClassName, (PCSZ)lpClassName)) { SetLastError(ERROR_OUTOFMEMORY); return (HWND)0; } } /* Copy it to a LARGE_STRING */ lstrClassName.Buffer = ClassName.Buffer; lstrClassName.Length = ClassName.Length; lstrClassName.MaximumLength = ClassName.MaximumLength; plstrClassName = &lstrClassName; } /* Initialize a LARGE_STRING */ RtlInitLargeString(&WindowName, lpWindowName, Unicode); // HACK: The current implementation expects the Window name to be UNICODE if (!Unicode) { NTSTATUS Status; PSTR AnsiBuffer = WindowName.Buffer; ULONG AnsiLength = WindowName.Length; WindowName.Length = 0; WindowName.MaximumLength = AnsiLength * sizeof(WCHAR); WindowName.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, WindowName.MaximumLength); if (!WindowName.Buffer) { SetLastError(ERROR_OUTOFMEMORY); goto cleanup; } Status = RtlMultiByteToUnicodeN(WindowName.Buffer, WindowName.MaximumLength, &WindowName.Length, AnsiBuffer, AnsiLength); if (!NT_SUCCESS(Status)) { goto cleanup; } } if(!hMenu && (dwStyle & (WS_OVERLAPPEDWINDOW | WS_POPUP))) { if(Unicode) { wceW.cbSize = sizeof(WNDCLASSEXW); if(GetClassInfoExW(hInstance, (LPCWSTR)lpClassName, &wceW) && wceW.lpszMenuName) { hMenu = LoadMenuW(hInstance, wceW.lpszMenuName); } } else { wceA.cbSize = sizeof(WNDCLASSEXA); if(GetClassInfoExA(hInstance, lpClassName, &wceA) && wceA.lpszMenuName) { hMenu = LoadMenuA(hInstance, wceA.lpszMenuName); } } } if (!Unicode) dwExStyle |= WS_EX_SETANSICREATOR; for(;;) { Handle = NtUserCreateWindowEx(dwExStyle, plstrClassName, NULL, &WindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam, dwFlags, NULL); if (Handle) break; if (!ClassFound) { save_error = GetLastError(); if ( save_error == ERROR_CANNOT_FIND_WND_CLASS ) { ClassFound = VersionRegisterClass(ClassName.Buffer, NULL, NULL, &hLibModule); if (ClassFound) continue; } } if (hLibModule) { save_error = GetLastError(); FreeLibrary(hLibModule); SetLastError(save_error); hLibModule = 0; } break; } #if 0 DbgPrint("[window] NtUserCreateWindowEx() == %d\n", Handle); #endif cleanup: if(!Unicode) { if (!IS_ATOM(lpClassName)) { RtlFreeUnicodeString(&ClassName); } RtlFreeLargeString(&WindowName); } return Handle; }