*
* Copyright 2001 Eric Pouech
* Copyright 2008 Owen Rudge
+ * Copyright 2022 Raymond Czerny
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
}
#endif
+#ifdef __REACTOS__
+
+/** Structure for in and out data when
+ * search for the cpl dialog of first instance
+ */
+typedef struct tagAppDlgFindData
+{
+ PCWSTR szAppFile; /**< Full path to applet library as search parameter */
+ UINT_PTR sAppletNo; /**< Number of applet in a system control library as search parameter */
+ ATOM aCPLName; /**< to read window property 'CPLName' */
+ ATOM aCPLFlags; /**< to read window property 'CPLFlags'*/
+ HWND hRunDLL; /**< to skip self instance */
+ HWND hDlgResult; /**< Returned dialog handle or NULL if not found */
+} AppDlgFindData;
+
+/**
+ * Callback function to search applet dialog
+ * @param hwnd A handle to a top-level window.
+ * @param lParam Pointer of AppDlgFindData
+ * @return TRUE: continue enumeration, FALSE: stop enumeration
+ */
+static BOOL CALLBACK
+Control_EnumWinProc(
+ _In_ HWND hwnd,
+ _In_ LPARAM lParam)
+{
+ AppDlgFindData* pData = (AppDlgFindData*)lParam;
+ WCHAR szClassName[256] = L"";
+
+ if (pData->hRunDLL == hwnd)
+ {
+ // Skip self instance
+ return TRUE;
+ }
+
+ if (GetClassNameW(hwnd, szClassName, _countof(szClassName)))
+ {
+ // Note: A comparison on identical is not possible, the class names are different.
+ // ReactOS: 'rundll32_window'
+ // WinXP: 'RunDLL'
+ // other OS: not checked
+ if (StrStrIW(szClassName, L"rundll32") != NULL)
+ {
+ UINT_PTR sAppletNo;
+
+ sAppletNo = (UINT_PTR)GetPropW(hwnd, (LPTSTR)MAKEINTATOM(pData->aCPLFlags));
+ if (sAppletNo == pData->sAppletNo)
+ {
+ HANDLE hRes;
+ WCHAR szAppFile[MAX_PATH];
+
+ hRes = GetPropW(hwnd, (LPTSTR)MAKEINTATOM(pData->aCPLName));
+ GlobalGetAtomNameW((ATOM)HandleToUlong(hRes), szAppFile, _countof(szAppFile));
+ if (wcscmp(szAppFile, pData->szAppFile) == 0)
+ {
+ HWND hDialog = GetLastActivePopup(hwnd);
+ if (IsWindow(hDialog))
+ {
+ pData->hDlgResult = hDialog;
+ return FALSE; // stop enumeration
+ }
+ }
+ }
+ }
+ }
+ return TRUE; // continue enumeration
+}
+#endif /* __REACTOS__ */
+
static void Control_DoLaunch(CPanel* panel, HWND hWnd, LPCWSTR wszCmd)
/* forms to parse:
* foo.cpl,@sp,str
#ifdef __REACTOS__
ULONG_PTR cookie;
BOOL bActivated;
+ ATOM aCPLName;
+ ATOM aCPLFlags;
+ ATOM aCPLPath;
+ AppDlgFindData findData;
#endif
/* we've been given a textual parameter (or none at all) */
if (sp == -1) {
#ifdef __REACTOS__
bActivated = (applet->hActCtx != INVALID_HANDLE_VALUE ? ActivateActCtx(applet->hActCtx, &cookie) : FALSE);
+
+ aCPLPath = GlobalFindAtomW(applet->cmd);
+ if (!aCPLPath)
+ {
+ aCPLPath = GlobalAddAtomW(applet->cmd);
+ }
+
+ aCPLName = GlobalFindAtomW(L"CPLName");
+ if (!aCPLName)
+ {
+ aCPLName = GlobalAddAtomW(L"CPLName");
+ }
+
+ aCPLFlags = GlobalFindAtomW(L"CPLFlags");
+ if (!aCPLFlags)
+ {
+ aCPLFlags = GlobalAddAtomW(L"CPLFlags");
+ }
+
+ findData.szAppFile = applet->cmd;
+ findData.sAppletNo = (UINT_PTR)(sp + 1);
+ findData.aCPLName = aCPLName;
+ findData.aCPLFlags = aCPLFlags;
+ findData.hRunDLL = applet->hWnd;
+ findData.hDlgResult = NULL;
+ // Find the dialog of this applet in the first instance.
+ // Note: The simpler functions "FindWindow" or "FindWindowEx" does not find this type of dialogs.
+ EnumWindows(Control_EnumWinProc, (LPARAM)&findData);
+ if (findData.hDlgResult)
+ {
+ BringWindowToTop(findData.hDlgResult);
+ }
+ else
+ {
+ SetPropW(applet->hWnd, (LPTSTR)MAKEINTATOM(aCPLName), (HANDLE)MAKEINTATOM(aCPLPath));
+ SetPropW(applet->hWnd, (LPTSTR)MAKEINTATOM(aCPLFlags), UlongToHandle(sp + 1));
#endif
if (!applet->proc(applet->hWnd, CPL_STARTWPARMSW, sp, (LPARAM)extraPmts))
applet->proc(applet->hWnd, CPL_DBLCLK, sp, applet->info[sp].data);
+#ifdef __REACTOS__
+ RemovePropW(applet->hWnd, applet->cmd);
+ GlobalDeleteAtom(aCPLPath);
+ }
+#endif
Control_UnloadApplet(applet);