// // This file contains some shell specific property sheet related code, // which includes: // 1. The logic which lets shell extensions add pages. // 2. The callback function to be called by those shell extensions. // but does not include: // 1. The property sheet UI code (should be in COMMCTRL). // 2. The file system specific property sheet pages. // #include "shellprv.h" #pragma hdrstop #ifdef CAIRO_DS #include "dsdata.h" #endif // // This function is a callback function from property sheet page extensions. // BOOL CALLBACK _AddPropSheetPage(HPROPSHEETPAGE hpage, LPARAM lParam) { PROPSHEETHEADER * ppsh = (PROPSHEETHEADER *)lParam; if (ppsh->nPages < MAX_FILE_PROP_PAGES) { ppsh->phpage[ppsh->nPages++] = hpage; return TRUE; } return FALSE; } // // This function enumerates all the property sheet page extensions for // specified class and let them add pages. // VOID DCA_AppendClassSheetInfo(HDCA hdca, HKEY hkeyProgID, LPPROPSHEETHEADER ppsh, LPDATAOBJECT pdtobj) { int i; for (i = 0; i < DCA_GetItemCount(hdca); i++) { LPSHELLEXTINIT psei; HRESULT hres = DCA_CreateInstance(hdca, i, &IID_IShellExtInit, &psei); if (hres==NOERROR) { IShellPropSheetExt * pspse; if (SUCCEEDED(psei->lpVtbl->Initialize(psei, NULL, pdtobj, hkeyProgID)) && SUCCEEDED(psei->lpVtbl->QueryInterface(psei, &IID_IShellPropSheetExt, &pspse))) { pspse->lpVtbl->AddPages(pspse, _AddPropSheetPage, (LPARAM)ppsh); pspse->lpVtbl->Release(pspse); } psei->lpVtbl->Release(psei); } } } HWND FindStubForPidl(LPCITEMIDLIST pidl) { HWND hwnd; for (hwnd = FindWindow(c_szStubWindowClass, NULL); hwnd; hwnd = GetWindow(hwnd, GW_HWNDNEXT)) { TCHAR szClass[80]; // find stub windows only GetClassName(hwnd, szClass, ARRAYSIZE(szClass)); if (lstrcmpi(szClass, c_szStubWindowClass) == 0) { int iClass; HANDLE hClassPidl; DWORD dwProcId; GetWindowThreadProcessId(hwnd, &dwProcId); hClassPidl = (HANDLE)SendMessage(hwnd, STUBM_GETDATA, 0, 0); if (hClassPidl) { LPBYTE lpb; lpb = (LPBYTE)SHLockShared(hClassPidl, dwProcId); if (lpb) { iClass = *(int *)lpb; if (iClass == SHELL_PROPSHEET_STUB_CLASS && ILIsEqual(pidl, (LPITEMIDLIST)(lpb+SIZEOF(int))) ) { SHUnlockShared(lpb); return hwnd; } SHUnlockShared(lpb); } } } } return NULL; } HWND FindOtherStub(HIDA hida) { LPITEMIDLIST pidl; HWND hwnd = NULL; if (hida && (HIDA_GetCount(hida) == 1) && (NULL != (pidl = HIDA_ILClone(hida, 0)))) { hwnd = FindStubForPidl(pidl); ILFree(pidl); } return hwnd; } HANDLE StuffStubWindowWithPidl(HWND hwnd, LPITEMIDLIST pidlT) { DWORD dwProcId; HANDLE hSharedClassPidl; UINT uidlSize; uidlSize = ILGetSize(pidlT); GetWindowThreadProcessId(hwnd, &dwProcId); hSharedClassPidl = SHAllocShared(NULL, SIZEOF(int)+uidlSize, dwProcId); if (hSharedClassPidl) { LPBYTE lpb = SHLockShared(hSharedClassPidl, dwProcId); if (lpb) { *(int *)lpb = SHELL_PROPSHEET_STUB_CLASS; memcpy(lpb+SIZEOF(int),pidlT, uidlSize); SHUnlockShared(lpb); SendMessage(hwnd, STUBM_SETDATA, (WPARAM)hSharedClassPidl, 0); return hSharedClassPidl; } SHFreeShared(hSharedClassPidl, dwProcId); } return NULL; } HANDLE StuffStubWindow(HWND hwnd, HIDA hida) { LPITEMIDLIST pidlT = NULL; HANDLE hClassPidl = NULL; if (hida && (HIDA_GetCount(hida) == 1) && (NULL != (pidlT = HIDA_ILClone(hida, 0)))) { hClassPidl = StuffStubWindowWithPidl(hwnd, pidlT); ILFree(pidlT); } return hClassPidl; } BOOL _IsAnyDuplicatedKey(HKEY ahkeys[], UINT ckeys, HKEY hkey) { UINT ikey; for (ikey=0; ikey 0) { _try { if (PropertySheet(&psh) >= 0) // IDOK or IDCANCEL (< 0 is error) fSuccess = TRUE; } _except(UnhandledExceptionFilter(GetExceptionInformation())) { DebugMsg(DM_ERROR, TEXT("PRSHT: Fault in property sheet")); } } else { ShellMessageBox(HINST_THISDLL, NULL, MAKEINTRESOURCE(IDS_NOPAGE), MAKEINTRESOURCE(IDS_DESKTOP), MB_OK|MB_ICONHAND); } // clean up the stub window and data SHFreeShared(hClassPidl,GetCurrentProcessId()); if (psh.hwndParent) DestroyWindow(psh.hwndParent); return fSuccess; }