static void test_ax_win(void) { BOOL ret; WNDCLASSEXW wcex; static const WCHAR AtlAxWin100[] = {'A','t','l','A','x','W','i','n','1','0','0',0}; static const WCHAR AtlAxWinLic100[] = {'A','t','l','A','x','W','i','n','L','i','c','1','0','0',0}; static HMODULE hinstance = 0; ret = AtlAxWinInit(); ok(ret, "AtlAxWinInit failed\n"); hinstance = GetModuleHandleA(NULL); memset(&wcex, 0, sizeof(wcex)); wcex.cbSize = sizeof(wcex); ret = GetClassInfoExW(hinstance, AtlAxWin100, &wcex); ok(ret, "AtlAxWin100 has not registered\n"); ok(wcex.style == (CS_GLOBALCLASS | CS_DBLCLKS), "wcex.style %08x\n", wcex.style); memset(&wcex, 0, sizeof(wcex)); wcex.cbSize = sizeof(wcex); ret = GetClassInfoExW(hinstance, AtlAxWinLic100, &wcex); ok(ret, "AtlAxWinLic100 has not registered\n"); ok(wcex.style == (CS_GLOBALCLASS | CS_DBLCLKS), "wcex.style %08x\n", wcex.style); }
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); } }
/* Author : mah Date : 13.06.2002 Description : Constructs window class InputBox */ CInputBox::CInputBox(HWND hWndParent) { HINSTANCE hInst = GetModuleHandle(NULL); WNDCLASSEXW wcex; if (!GetClassInfoExW(hInst, L"InputBox", &wcex)) { wcex.cbSize = sizeof(WNDCLASSEXW); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = (WNDPROC)WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInst; wcex.hIcon = NULL;//LoadIcon(hInst, (LPCTSTR)IDI_MYINPUTBOX); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW); wcex.lpszMenuName = NULL; wcex.lpszClassName = L"InputBox"; wcex.hIconSm = NULL; if (RegisterClassExW(&wcex) == 0) MessageBoxW(NULL, L"Can't create CInputBox!", L"Error", MB_OK); } m_hWndParent = hWndParent; Text = NULL; }
/*********************************************************************** * AtlModuleRegisterWndClassInfoW [ATL.@] * * PARAMS * pm [IO] Information about the module registering the window. * wci [IO] Information about the window being registered. * pProc [O] Window procedure of the registered class. * * RETURNS * Atom representing the registered class. * * NOTES * Can be called multiple times without error, unlike RegisterClassEx(). * * If the class name is NULL, then a class with a name of "ATLxxxxxxxx" is * registered, where the 'x's represent a unique value. * */ ATOM WINAPI AtlModuleRegisterWndClassInfoW(_ATL_MODULEW *pm, _ATL_WNDCLASSINFOW *wci, WNDPROC *pProc) { ATOM atom; FIXME("%p %p %p semi-stub\n", pm, wci, pProc); atom = wci->m_atom; if (!atom) { WNDCLASSEXW wc; TRACE("wci->m_wc.lpszClassName = %s\n", debugstr_w(wci->m_wc.lpszClassName)); if (wci->m_lpszOrigName) FIXME( "subclassing %s not implemented\n", debugstr_w(wci->m_lpszOrigName)); if (!wci->m_wc.lpszClassName) { static const WCHAR szFormat[] = {'A','T','L','%','0','8','l','x',0}; snprintfW(wci->m_szAutoName, ARRAY_SIZE(wci->m_szAutoName), szFormat, (UINT_PTR)wci); TRACE("auto-generated class name %s\n", debugstr_w(wci->m_szAutoName)); wci->m_wc.lpszClassName = wci->m_szAutoName; } atom = GetClassInfoExW(pm->m_hInst, wci->m_wc.lpszClassName, &wc); if (!atom) { wci->m_wc.hInstance = pm->m_hInst; wci->m_wc.hCursor = LoadCursorW( wci->m_bSystemCursor ? NULL : pm->m_hInst, wci->m_lpszCursorID ); atom = RegisterClassExW(&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 MyCreateWindowExW(DWORD dwExStyle, LPCWSTR lpClassName, LPCWSTR lpWindowName, DWORD dwStyle, int X, int Y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam) { debuglog(LCF_WINDOW, __FUNCTION__ " called.\n"); createWindowDepth++; HWND oldGamehwnd = gamehwnd; ThreadLocalStuff& curtls = tls; curtls.callerisuntrusted++; curtls.treatDLLLoadsAsClient++; HWND hwnd = CreateWindowExW(dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam); 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 0 // FIXME should be enabled but currently breaks Iji due to some bug if(hwnd && createWindowDepth == 0) { if(!oldGamehwnd) { curtls.createdFirstWindow = true; gamehwnd = hwnd; } //WNDCLASSEXA cls = { sizeof(WNDCLASSEXA) }; //GetClassInfoExA(hInstance, lpClassName, &cls); WNDPROC oldProc = (WNDPROC)MyGetWindowLongW(hwnd, GWL_WNDPROC); if(!oldProc) { WNDCLASSEXW cls = { sizeof(WNDCLASSEXW) }; GetClassInfoExW(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); debuglog(LCF_WINDOW, "oldProc[0x%X] = 0x%X\n", hwnd, oldProc); hwndToOrigHandler[hwnd] = oldProc; SetWindowLongW(hwnd, GWL_WNDPROC, (LONG)MyWndProcW); 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, false); DispatchMessageInternal(hwnd, WM_SETFOCUS, 0, 0, false); /*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; };*/ //SendMessageW(hwnd, toggleWhitelistMessage(WM_WINDOWPOSCHANGED), 0, (LPARAM)&pos); CREATESTRUCTW 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, false); // trying to get the stupid splash screen to work, not sure how to fake the paint event well enough for it //InvalidateRect(hwnd, NULL, TRUE); //PostMessageInternal(hwnd, WM_PAINT, 0, 0, false); //InvalidateRect(hwnd, NULL, TRUE); //DispatchMessageInternal(hwnd, WM_PAINT, 0, 0, false); } #endif return hwnd; }
// Если (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; }
static void test_ax_win(void) { DWORD ret, ret_size, i; HRESULT res; HWND hwnd; HANDLE hfile; IUnknown *control; WNDPROC wndproc[2] = {NULL, NULL}; WCHAR file_uri1W[MAX_PATH], pathW[MAX_PATH]; WNDCLASSEXW wcex; static HMODULE hinstance = 0; static const WCHAR cls_names[][16] = { {'A','t','l','A','x','W','i','n','1','0','0',0}, {'A','t','l','A','x','W','i','n','L','i','c','1','0','0',0} }; ret = AtlAxWinInit(); ok(ret, "AtlAxWinInit failed\n"); hinstance = GetModuleHandleA(NULL); for (i = 0; i < 2; i++) { memset(&wcex, 0, sizeof(wcex)); wcex.cbSize = sizeof(wcex); ret = GetClassInfoExW(hinstance, cls_names[i], &wcex); ok(ret, "%s has not registered\n", wine_dbgstr_w(cls_names[i])); ok(wcex.style == (CS_GLOBALCLASS | CS_DBLCLKS), "wcex.style %08x\n", wcex.style); wndproc[i] = wcex.lpfnWndProc; hwnd = CreateWindowW(cls_names[i], NULL, 0, 100, 100, 100, 100, NULL, NULL, NULL, NULL); ok(hwnd != NULL, "CreateWindow failed!\n"); control = (IUnknown *)0xdeadbeef; res = AtlAxGetControl(hwnd, &control); ok(res == E_FAIL, "Expected E_FAIL, returned %08x\n", res); ok(!control, "returned %p\n", control); if (control) IUnknown_Release(control); DestroyWindow(hwnd); hwnd = CreateWindowW(cls_names[i], emptyW, 0, 100, 100, 100, 100, NULL, NULL, NULL, NULL); ok(hwnd != NULL, "CreateWindow failed!\n"); control = (IUnknown *)0xdeadbeef; res = AtlAxGetControl(hwnd, &control); ok(res == E_FAIL, "Expected E_FAIL, returned %08x\n", res); ok(!control, "returned %p\n", control); if (control) IUnknown_Release(control); DestroyWindow(hwnd); hwnd = CreateWindowW(cls_names[i], randomW, 0, 100, 100, 100, 100, NULL, NULL, NULL, NULL); todo_wine ok(!hwnd, "returned %p\n", hwnd); if(hwnd) DestroyWindow(hwnd); hwnd = CreateWindowW(cls_names[i], progid1W, 0, 100, 100, 100, 100, NULL, NULL, NULL, NULL); ok(hwnd != NULL, "CreateWindow failed!\n"); control = NULL; res = AtlAxGetControl(hwnd, &control); ok(res == S_OK, "AtlAxGetControl failed with res %08x\n", res); ok(control != NULL, "AtlAxGetControl failed!\n"); IUnknown_Release(control); DestroyWindow(hwnd); hwnd = CreateWindowW(cls_names[i], clsid1W, 0, 100, 100, 100, 100, NULL, NULL, NULL, NULL); ok(hwnd != NULL, "CreateWindow failed!\n"); control = NULL; res = AtlAxGetControl(hwnd, &control); ok(res == S_OK, "AtlAxGetControl failed with res %08x\n", res); ok(control != NULL, "AtlAxGetControl failed!\n"); IUnknown_Release(control); DestroyWindow(hwnd); hwnd = CreateWindowW(cls_names[i], url1W, 0, 100, 100, 100, 100, NULL, NULL, NULL, NULL); ok(hwnd != NULL, "CreateWindow failed!\n"); control = NULL; res = AtlAxGetControl(hwnd, &control); ok(res == S_OK, "AtlAxGetControl failed with res %08x\n", res); ok(control != NULL, "AtlAxGetControl failed!\n"); IUnknown_Release(control); DestroyWindow(hwnd); /* test html stream with "MSHTML:" prefix */ hwnd = CreateWindowW(cls_names[i], mshtml1W, 0, 100, 100, 100, 100, NULL, NULL, NULL, NULL); ok(hwnd != NULL, "CreateWindow failed!\n"); control = NULL; res = AtlAxGetControl(hwnd, &control); ok(res == S_OK, "AtlAxGetControl failed with res %08x\n", res); ok(control != NULL, "AtlAxGetControl failed!\n"); IUnknown_Release(control); DestroyWindow(hwnd); hwnd = CreateWindowW(cls_names[i], mshtml2W, 0, 100, 100, 100, 100, NULL, NULL, NULL, NULL); ok(hwnd != NULL, "CreateWindow failed!\n"); control = NULL; res = AtlAxGetControl(hwnd, &control); ok(res == S_OK, "AtlAxGetControl failed with res %08x\n", res); ok(control != NULL, "AtlAxGetControl failed!\n"); IUnknown_Release(control); DestroyWindow(hwnd); /* test html stream without "MSHTML:" prefix */ hwnd = CreateWindowW(cls_names[i], mshtml3W, 0, 100, 100, 100, 100, NULL, NULL, NULL, NULL); todo_wine ok(!hwnd, "returned %p\n", hwnd); if(hwnd) DestroyWindow(hwnd); ret = GetTempPathW(MAX_PATH, pathW); ok(ret, "GetTempPath failed!\n"); lstrcatW(pathW, html_fileW); hfile = CreateFileW(pathW, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, 0); ok(hfile != INVALID_HANDLE_VALUE, "failed to create file\n"); ret = WriteFile(hfile, html_str, sizeof(html_str), &ret_size, NULL); ok(ret, "WriteFile failed\n"); CloseHandle(hfile); /* test C:// scheme */ hwnd = CreateWindowW(cls_names[i], pathW, 0, 100, 100, 100, 100, NULL, NULL, NULL, NULL); ok(hwnd != NULL, "CreateWindow failed!\n"); control = NULL; res = AtlAxGetControl(hwnd, &control); ok(res == S_OK, "AtlAxGetControl failed with res %08x\n", res); ok(control != NULL, "AtlAxGetControl failed!\n"); IUnknown_Release(control); DestroyWindow(hwnd); /* test file:// scheme */ lstrcpyW(file_uri1W, fileW); lstrcatW(file_uri1W, pathW); hwnd = CreateWindowW(cls_names[i], file_uri1W, 0, 100, 100, 100, 100, NULL, NULL, NULL, NULL); ok(hwnd != NULL, "CreateWindow failed!\n"); control = NULL; res = AtlAxGetControl(hwnd, &control); ok(res == S_OK, "AtlAxGetControl failed with res %08x\n", res); ok(control != NULL, "AtlAxGetControl failed!\n"); IUnknown_Release(control); DestroyWindow(hwnd); /* test file:// scheme on non-existent file */ ret = DeleteFileW(pathW); ok(ret, "DeleteFile failed!\n"); hwnd = CreateWindowW(cls_names[i], file_uri1W, 0, 100, 100, 100, 100, NULL, NULL, NULL, NULL); ok(hwnd != NULL, "CreateWindow failed!\n"); control = NULL; res = AtlAxGetControl(hwnd, &control); ok(res == S_OK, "AtlAxGetControl failed with res %08x\n", res); ok(control != NULL, "AtlAxGetControl failed!\n"); IUnknown_Release(control); DestroyWindow(hwnd); } todo_wine ok(wndproc[0] != wndproc[1], "expected different proc!\n"); }