mirror of
https://github.com/reactos/reactos.git
synced 2024-09-29 05:54:05 +00:00
[SHELL32]
- Properly close Open With dialog window (EndDialog works only for modal dialogs, modeless dialogs should be destroyed with DestroyWindow instead). Fixes folder window hang if Open With windows was opened twice (and also a window leak). svn path=/trunk/; revision=54701
This commit is contained in:
parent
235496f021
commit
13b53b78ab
|
@ -77,11 +77,10 @@ COpenWithMenu::~COpenWithMenu()
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID
|
static VOID
|
||||||
AddItem(HMENU hMenu, UINT idCmdFirst)
|
AddChooseProgramItem(HMENU hMenu, UINT idCmdFirst)
|
||||||
{
|
{
|
||||||
MENUITEMINFOW mii;
|
MENUITEMINFOW mii;
|
||||||
WCHAR szBuffer[MAX_PATH];
|
WCHAR szBuffer[MAX_PATH];
|
||||||
static const WCHAR szChoose[] = { 'C', 'h', 'o', 'o', 's', 'e', ' ', 'P', 'r', 'o', 'g', 'r', 'a', 'm', '.', '.', '.', 0 };
|
|
||||||
|
|
||||||
ZeroMemory(&mii, sizeof(mii));
|
ZeroMemory(&mii, sizeof(mii));
|
||||||
mii.cbSize = sizeof(mii);
|
mii.cbSize = sizeof(mii);
|
||||||
|
@ -91,11 +90,9 @@ AddItem(HMENU hMenu, UINT idCmdFirst)
|
||||||
InsertMenuItemW(hMenu, -1, TRUE, &mii);
|
InsertMenuItemW(hMenu, -1, TRUE, &mii);
|
||||||
|
|
||||||
if (!LoadStringW(shell32_hInstance, IDS_OPEN_WITH_CHOOSE, szBuffer, sizeof(szBuffer) / sizeof(WCHAR)))
|
if (!LoadStringW(shell32_hInstance, IDS_OPEN_WITH_CHOOSE, szBuffer, sizeof(szBuffer) / sizeof(WCHAR)))
|
||||||
wcscpy(szBuffer, szChoose);
|
wcscpy(szBuffer, L"Choose Program...");
|
||||||
|
|
||||||
szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0';
|
mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE | MIIM_STRING;
|
||||||
|
|
||||||
mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
|
|
||||||
mii.fType = MFT_STRING;
|
mii.fType = MFT_STRING;
|
||||||
mii.fState = MFS_ENABLED;
|
mii.fState = MFS_ENABLED;
|
||||||
mii.wID = idCmdFirst;
|
mii.wID = idCmdFirst;
|
||||||
|
@ -106,7 +103,7 @@ AddItem(HMENU hMenu, UINT idCmdFirst)
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID
|
static VOID
|
||||||
LoadOWItems(POPEN_WITH_CONTEXT pContext, LPCWSTR szName)
|
LoadOpenWithItems(POPEN_WITH_CONTEXT pContext, LPCWSTR szName)
|
||||||
{
|
{
|
||||||
const WCHAR * szExt;
|
const WCHAR * szExt;
|
||||||
WCHAR szPath[100];
|
WCHAR szPath[100];
|
||||||
|
@ -165,7 +162,7 @@ HRESULT WINAPI COpenWithMenu::QueryContextMenu(
|
||||||
Context.hMenu = hSubMenu;
|
Context.hMenu = hSubMenu;
|
||||||
Context.idCmdFirst = idCmdFirst;
|
Context.idCmdFirst = idCmdFirst;
|
||||||
/* load items */
|
/* load items */
|
||||||
LoadOWItems(&Context, szPath);
|
LoadOpenWithItems(&Context, szPath);
|
||||||
if (!Context.Count)
|
if (!Context.Count)
|
||||||
{
|
{
|
||||||
DestroyMenu(hSubMenu);
|
DestroyMenu(hSubMenu);
|
||||||
|
@ -175,7 +172,7 @@ HRESULT WINAPI COpenWithMenu::QueryContextMenu(
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AddItem(hSubMenu, Context.idCmdFirst++);
|
AddChooseProgramItem(hSubMenu, Context.idCmdFirst++);
|
||||||
count = Context.idCmdFirst - idCmdFirst;
|
count = Context.idCmdFirst - idCmdFirst;
|
||||||
/* verb start at index zero */
|
/* verb start at index zero */
|
||||||
wId = count - 1;
|
wId = count - 1;
|
||||||
|
@ -232,9 +229,9 @@ FreeListItems(HWND hwndDlg)
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL
|
static BOOL
|
||||||
HideApplicationFromList(WCHAR * pFileName)
|
HideApplicationFromList(WCHAR *pFileName)
|
||||||
{
|
{
|
||||||
WCHAR szBuffer[100] = {'A', 'p', 'p', 'l', 'i', 'c', 'a', 't', 'i', 'o', 'n', 's', '\\', 0};
|
WCHAR szBuffer[100] = L"Applications\\";
|
||||||
DWORD dwSize = 0;
|
DWORD dwSize = 0;
|
||||||
LONG result;
|
LONG result;
|
||||||
|
|
||||||
|
@ -260,10 +257,10 @@ WriteStaticShellExtensionKey(HKEY hRootKey, const WCHAR * pVerb, WCHAR *pFullPat
|
||||||
{
|
{
|
||||||
HKEY hShell;
|
HKEY hShell;
|
||||||
LONG result;
|
LONG result;
|
||||||
WCHAR szBuffer[MAX_PATH+10] = {'s', 'h', 'e', 'l', 'l', '\\', 0 };
|
WCHAR szBuffer[MAX_PATH+10] = L"shell\\";
|
||||||
|
|
||||||
if (wcslen(pVerb) > (sizeof(szBuffer) / sizeof(WCHAR)) - 15 ||
|
if (wcslen(pVerb) > (sizeof(szBuffer) / sizeof(WCHAR)) - 15 ||
|
||||||
wcslen(pFullPath) > (sizeof(szBuffer) / sizeof(WCHAR)) - 4)
|
wcslen(pFullPath) > (sizeof(szBuffer) / sizeof(WCHAR)) - 4)
|
||||||
{
|
{
|
||||||
ERR("insufficient buffer\n");
|
ERR("insufficient buffer\n");
|
||||||
return;
|
return;
|
||||||
|
@ -528,7 +525,7 @@ OpenWithProgrammDlg(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
SetDlgItemTextW(hwndDlg, 14001, szBuffer);
|
SetDlgItemTextW(hwndDlg, 14001, szBuffer);
|
||||||
ZeroMemory(&Context, sizeof(OPEN_WITH_CONTEXT));
|
ZeroMemory(&Context, sizeof(OPEN_WITH_CONTEXT));
|
||||||
Context.hDlgCtrl = GetDlgItem(hwndDlg, 14002);
|
Context.hDlgCtrl = GetDlgItem(hwndDlg, 14002);
|
||||||
LoadOWItems(&Context, poainfo->pcszFile);
|
LoadOpenWithItems(&Context, poainfo->pcszFile);
|
||||||
SendMessage(Context.hDlgCtrl, LB_SETCURSEL, 0, 0);
|
SendMessage(Context.hDlgCtrl, LB_SETCURSEL, 0, 0);
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -563,11 +560,11 @@ OpenWithProgrammDlg(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
ExecuteOpenItem(pItemContext, poainfo->pcszFile);
|
ExecuteOpenItem(pItemContext, poainfo->pcszFile);
|
||||||
}
|
}
|
||||||
FreeListItems(hwndDlg);
|
FreeListItems(hwndDlg);
|
||||||
EndDialog(hwndDlg, 1);
|
DestroyWindow(hwndDlg);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
case 14006: /* cancel */
|
case 14006: /* cancel */
|
||||||
FreeListItems(hwndDlg);
|
FreeListItems(hwndDlg);
|
||||||
EndDialog(hwndDlg, 0);
|
DestroyWindow(hwndDlg);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -626,7 +623,7 @@ OpenWithProgrammDlg(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
break;
|
break;
|
||||||
case WM_CLOSE:
|
case WM_CLOSE:
|
||||||
FreeListItems(hwndDlg);
|
FreeListItems(hwndDlg);
|
||||||
EndDialog(hwndDlg, 0);
|
DestroyWindow(hwndDlg);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -663,13 +660,13 @@ FreeMenuItemContext(HMENU hMenu)
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT WINAPI
|
HRESULT WINAPI
|
||||||
COpenWithMenu::InvokeCommand(LPCMINVOKECOMMANDINFO lpici )
|
COpenWithMenu::InvokeCommand(LPCMINVOKECOMMANDINFO lpici)
|
||||||
{
|
{
|
||||||
MENUITEMINFOW mii;
|
MENUITEMINFOW mii;
|
||||||
|
|
||||||
ERR("This %p wId %x count %u verb %x\n", this, wId, count, LOWORD(lpici->lpVerb));
|
ERR("This %p wId %x count %u verb %x\n", this, wId, count, LOWORD(lpici->lpVerb));
|
||||||
|
|
||||||
if (wId < LOWORD(lpici->lpVerb))
|
if (HIWORD(lpici->lpVerb) != 0 || LOWORD(lpici->lpVerb) > wId)
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
|
||||||
if (wId == LOWORD(lpici->lpVerb))
|
if (wId == LOWORD(lpici->lpVerb))
|
||||||
|
@ -1004,19 +1001,24 @@ LoadItemFromHKCU(POPEN_WITH_CONTEXT pContext, const WCHAR * szExt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT
|
HRESULT WINAPI
|
||||||
COpenWithMenu::LoadOpenWithItems(IDataObject *pdtobj)
|
COpenWithMenu::Initialize(LPCITEMIDLIST pidlFolder,
|
||||||
|
IDataObject *pdtobj,
|
||||||
|
HKEY hkeyProgID)
|
||||||
{
|
{
|
||||||
STGMEDIUM medium;
|
STGMEDIUM medium;
|
||||||
FORMATETC fmt;
|
FORMATETC fmt;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
LPIDA pida;
|
LPIDA pida;
|
||||||
LPCITEMIDLIST pidlFolder;
|
LPCITEMIDLIST pidlFolder2;
|
||||||
LPCITEMIDLIST pidlChild;
|
LPCITEMIDLIST pidlChild;
|
||||||
LPCITEMIDLIST pidl;
|
LPCITEMIDLIST pidl;
|
||||||
DWORD dwType;
|
|
||||||
LPWSTR pszExt;
|
LPWSTR pszExt;
|
||||||
static const WCHAR szShortCut[] = L".lnk";
|
|
||||||
|
TRACE("This %p\n", this);
|
||||||
|
|
||||||
|
if (pdtobj == NULL)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
fmt.cfFormat = RegisterClipboardFormatW(CFSTR_SHELLIDLIST);
|
fmt.cfFormat = RegisterClipboardFormatW(CFSTR_SHELLIDLIST);
|
||||||
fmt.ptd = NULL;
|
fmt.ptd = NULL;
|
||||||
|
@ -1035,10 +1037,10 @@ COpenWithMenu::LoadOpenWithItems(IDataObject *pdtobj)
|
||||||
pida = (LPIDA)GlobalLock(medium.hGlobal);
|
pida = (LPIDA)GlobalLock(medium.hGlobal);
|
||||||
ASSERT(pida->cidl == 1);
|
ASSERT(pida->cidl == 1);
|
||||||
|
|
||||||
pidlFolder = (LPCITEMIDLIST) ((LPBYTE)pida + pida->aoffset[0]);
|
pidlFolder2 = (LPCITEMIDLIST) ((LPBYTE)pida + pida->aoffset[0]);
|
||||||
pidlChild = (LPCITEMIDLIST) ((LPBYTE)pida + pida->aoffset[1]);
|
pidlChild = (LPCITEMIDLIST) ((LPBYTE)pida + pida->aoffset[1]);
|
||||||
|
|
||||||
pidl = ILCombine(pidlFolder, pidlChild);
|
pidl = ILCombine(pidlFolder2, pidlChild);
|
||||||
|
|
||||||
GlobalUnlock(medium.hGlobal);
|
GlobalUnlock(medium.hGlobal);
|
||||||
GlobalFree(medium.hGlobal);
|
GlobalFree(medium.hGlobal);
|
||||||
|
@ -1068,40 +1070,25 @@ COpenWithMenu::LoadOpenWithItems(IDataObject *pdtobj)
|
||||||
SHFree((void*)pidl);
|
SHFree((void*)pidl);
|
||||||
TRACE("szPath %s\n", debugstr_w(szPath));
|
TRACE("szPath %s\n", debugstr_w(szPath));
|
||||||
|
|
||||||
if (GetBinaryTypeW(szPath, &dwType))
|
|
||||||
{
|
|
||||||
TRACE("path is a executable %x\n", dwType);
|
|
||||||
return E_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
pszExt = wcsrchr(szPath, L'.');
|
pszExt = wcsrchr(szPath, L'.');
|
||||||
if (pszExt && !_wcsicmp(pszExt, szShortCut))
|
|
||||||
|
if (pszExt)
|
||||||
{
|
{
|
||||||
TRACE("pidl is a shortcut\n");
|
if (!_wcsicmp(pszExt, L".exe") || !_wcsicmp(pszExt, L".lnk"))
|
||||||
return E_FAIL;
|
{
|
||||||
|
TRACE("path is a executable or shortcut\n");
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT WINAPI
|
|
||||||
COpenWithMenu::Initialize(LPCITEMIDLIST pidlFolder,
|
|
||||||
IDataObject *pdtobj,
|
|
||||||
HKEY hkeyProgID)
|
|
||||||
{
|
|
||||||
TRACE("This %p\n", this);
|
|
||||||
|
|
||||||
if (pdtobj == NULL)
|
|
||||||
return E_INVALIDARG;
|
|
||||||
return LoadOpenWithItems(pdtobj);
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT WINAPI
|
HRESULT WINAPI
|
||||||
SHOpenWithDialog(HWND hwndParent,
|
SHOpenWithDialog(HWND hwndParent,
|
||||||
const OPENASINFO *poainfo)
|
const OPENASINFO *poainfo)
|
||||||
{
|
{
|
||||||
MSG msg;
|
MSG msg;
|
||||||
BOOL bRet;
|
|
||||||
HWND hwnd;
|
HWND hwnd;
|
||||||
|
|
||||||
if (poainfo->pcszClass == NULL && poainfo->pcszFile == NULL)
|
if (poainfo->pcszClass == NULL && poainfo->pcszFile == NULL)
|
||||||
|
@ -1113,15 +1100,17 @@ SHOpenWithDialog(HWND hwndParent,
|
||||||
ERR("Failed to create dialog\n");
|
ERR("Failed to create dialog\n");
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ShowWindow(hwnd, SW_SHOWNORMAL);
|
ShowWindow(hwnd, SW_SHOWNORMAL);
|
||||||
|
|
||||||
while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
|
while (GetMessage(&msg, NULL, 0, 0) != 0 && IsWindow(hwnd))
|
||||||
{
|
{
|
||||||
if (!IsWindow(hwnd) || !IsDialogMessage(hwnd, &msg))
|
if (!IsDialogMessage(hwnd, &msg))
|
||||||
{
|
{
|
||||||
TranslateMessage(&msg);
|
TranslateMessage(&msg);
|
||||||
DispatchMessage(&msg);
|
DispatchMessage(&msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,6 @@ class COpenWithMenu :
|
||||||
public:
|
public:
|
||||||
COpenWithMenu();
|
COpenWithMenu();
|
||||||
~COpenWithMenu();
|
~COpenWithMenu();
|
||||||
HRESULT LoadOpenWithItems(IDataObject *pdtobj);
|
|
||||||
|
|
||||||
// IContextMenu
|
// IContextMenu
|
||||||
virtual HRESULT WINAPI QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags);
|
virtual HRESULT WINAPI QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags);
|
||||||
|
|
Loading…
Reference in a new issue