Beispiel #1
0
HMENU WINAPI __LoadMenuA(HINSTANCE hInstance, LPCSTR lpMenuName) {
	HMENU hmenu = LoadMenuA(hInstance, lpMenuName);
	if (lpMenuName == MAKEINTRESOURCEA(IDR_MAIN_MENU)) {
		InitVDubAuoMenu(hmenu);
	}
	return hmenu;
}
Beispiel #2
0
/* Background menu implementation */
static HRESULT WINAPI BackgroundMenu_QueryContextMenu(
	IContextMenu3 *iface,
	HMENU hMenu,
	UINT indexMenu,
	UINT idCmdFirst,
	UINT idCmdLast,
	UINT uFlags)
{
    ContextMenu *This = impl_from_IContextMenu3(iface);
    HMENU hMyMenu;
    UINT idMax;
    HRESULT hr;

    TRACE("(%p)->(hmenu=%p indexmenu=%x cmdfirst=%x cmdlast=%x flags=%x )\n",
          This, hMenu, indexMenu, idCmdFirst, idCmdLast, uFlags);

    hMyMenu = LoadMenuA(shell32_hInstance, "MENU_002");
    if (uFlags & CMF_DEFAULTONLY)
    {
        HMENU ourMenu = GetSubMenu(hMyMenu,0);
        UINT oldDef = GetMenuDefaultItem(hMenu,TRUE,GMDI_USEDISABLED);
        UINT newDef = GetMenuDefaultItem(ourMenu,TRUE,GMDI_USEDISABLED);
        if (newDef != oldDef)
            SetMenuDefaultItem(hMenu,newDef,TRUE);
        if (newDef!=0xFFFFFFFF)
            hr =  MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, newDef+1);
        else
            hr =  MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, 0);
    }
    else
    {
        idMax = Shell_MergeMenus (hMenu, GetSubMenu(hMyMenu,0), indexMenu,
                                  idCmdFirst, idCmdLast, MM_SUBMENUSHAVEIDS);
        hr =  MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, idMax-idCmdFirst);
    }
    DestroyMenu(hMyMenu);

    TRACE("(%p)->returning 0x%x\n",This,hr);
    return hr;
}
// Если (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);
	}
}
Beispiel #4
0
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;
}