|
|
/* cmdlink.c - Handles command line/pseudo-link objects.
*/
#include "packager.h"
#include <shellapi.h>
DECLSPEC_IMPORT BOOL SafeOpenPromptForPackager(HWND hwnd, PCWSTR pszFile, BOOL bFromCommandLine);
DWORD CmlWaitForChildProc( LPVOID lpv ) { if (WaitForSingleObject((HANDLE)lpv, INFINITE) == 0) { if (gfInvisible) { PostMessage(ghwndFrame, WM_SYSCOMMAND, SC_CLOSE, 0L); } }
CloseHandle((HANDLE)lpv);
return 0; }
void _CmlExecute(LPCSTR pszFile, LPCSTR pszParams) { HRESULT hr;
WCHAR szUrlName[MAX_PATH]; WCHAR szDialogName[MAX_PATH]; BOOL bResult; SHELLEXECUTEINFO sexi = {0}; DWORD err = NO_ERROR;
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, pszFile, -1, szUrlName, ARRAYSIZE(szUrlName)); StringCchCopyW(szDialogName, ARRAYSIZE(szDialogName), szUrlName); if(pszParams && *pszParams) { StringCchCatW(szDialogName, ARRAYSIZE(szDialogName), L" "); MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, pszParams, -1, szUrlName, ARRAYSIZE(szUrlName)); StringCchCatW(szDialogName, ARRAYSIZE(szDialogName),szUrlName); }
if(SafeOpenPromptForPackager(NULL, szDialogName, TRUE)) { // Now we can execute the link file.
sexi.cbSize = sizeof(sexi); sexi.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_DDEWAIT | SEE_MASK_NOZONECHECKS ; sexi.lpFile = pszFile; sexi.lpParameters = pszParams; sexi.nShow = SW_SHOWNORMAL;
if (ShellExecuteEx(&sexi)) { if (sexi.hProcess != NULL) { // Start a thread to wait on the app and close packager once it has ended
DWORD id; HANDLE hThd = CreateThread(NULL, 0, CmlWaitForChildProc, sexi.hProcess, 0, &id ); if (hThd) { CloseHandle(hThd); } else { CloseHandle(sexi.hProcess); err = GetLastError(); } } } else { err = GetLastError(); }
if (err != NO_ERROR) ErrorMessage((err == ERROR_NO_ASSOCIATION) ? E_FAILED_TO_FIND_ASSOCIATION : E_FAILED_TO_EXECUTE_COMMAND); } }
/* CmlActivate() - Activate the command line/pseudo-linked file.
*/ VOID CmlActivate(LPCML lpcml) { LPSTR pchTemp = lpcml->szCommand; CHAR chSave = 0; BOOL fInQuote = FALSE;
/* skip leading spaces */ while (*pchTemp && *pchTemp == CHAR_SPACE) pchTemp = CharNext(pchTemp);
/* find first non-quoted space */ for (; *pchTemp && (*pchTemp != CHAR_SPACE || fInQuote); pchTemp = CharNext(pchTemp)) { if (*pchTemp == CHAR_QUOTE) { fInQuote = !fInQuote; } }
if (*pchTemp) { chSave = *pchTemp; *pchTemp++ = 0; }
DPRINT("packager: Calling ShellExecute"); _CmlExecute(lpcml->szCommand, pchTemp); DPRINT("packager: Back from ShellExecute");
if (chSave) *(--pchTemp) = chSave; }
/* CmlClone() -
*/ LPCML CmlClone( LPCML lpcml ) { return CmlCreate(lpcml->szCommand, lpcml->fCmdIsLink); }
/* CmlCreate() -
*/ LPCML CmlCreateWorker( LPSTR lpstrCmd, BOOL fCmdIsLink, BOOL fFileName) { HANDLE hdata = NULL; LPCML lpcml = NULL;
if (!(hdata = GlobalAlloc(GMEM_MOVEABLE, sizeof(CML))) || !(lpcml = (LPCML)GlobalLock(hdata))) goto errRtn;
// Store the data in the window itself
lpcml->hdata = hdata; lpcml->fCmdIsLink = fCmdIsLink;
/*
* If it is not a single filename, * or the filename does not have a space in it, * or the 'filename' has double qoute characters in it, then * just copy it without quoting. */ if (!fFileName || strchr( lpstrCmd, CHAR_SPACE ) == NULL || strchr( lpstrCmd, CHAR_QUOTE ) != NULL)
StringCchCopy(lpcml->szCommand, ARRAYSIZE(lpcml->szCommand), lpstrCmd);
else { LPSTR psz = lpcml->szCommand; *psz++ = CHAR_QUOTE; StringCchCopy(psz, ARRAYSIZE(lpcml->szCommand) - 1, lpstrCmd); StringCchCat(lpcml->szCommand, ARRAYSIZE(lpcml->szCommand), SZ_QUOTE); } CmlFixBounds(lpcml);
return lpcml;
errRtn: ErrorMessage(E_FAILED_TO_CREATE_CHILD_WINDOW);
if (lpcml) GlobalUnlock(hdata);
if (hdata) GlobalFree(hdata);
return NULL; }
/* CmlDelete() - Wipe out the command line.
*/ VOID CmlDelete( LPCML lpcml ) { HANDLE hdata;
if (lpcml) { GlobalUnlock(hdata = lpcml->hdata); GlobalFree(hdata); } }
/* CmlDraw() - Draw the command line, centered nicely.
*/ VOID CmlDraw( LPCML lpcml, HDC hdc, LPRECT lprc, INT xHSB, BOOL fFocus ) { HFONT hfont; RECT rcFocus; CHAR szDesc[CBSTRINGMAX]; CHAR szFile[CBCMDLINKMAX]; CHAR szMessage[CBSTRINGMAX + CBCMDLINKMAX]; RECT rc;
hfont = SelectObject(hdc, ghfontChild);
if (lpcml->fCmdIsLink) { LoadString(ghInst, IDS_LINKTOFILE, szDesc, CharCountOf(szDesc)); StringCchCopy(szFile, ARRAYSIZE(szFile), lpcml->szCommand); Normalize(szFile); StringCchPrintf(szMessage, ARRAYSIZE(szMessage), szDesc, (LPSTR)szFile);
DrawText(hdc, szMessage, -1, lprc, DT_SINGLELINE | DT_NOPREFIX | DT_CENTER | DT_VCENTER);
if (fFocus) { rcFocus = *lprc; DrawText(hdc, szMessage, -1, &rcFocus, DT_CALCRECT | DT_SINGLELINE | DT_NOPREFIX | DT_LEFT | DT_TOP); OffsetRect(&rcFocus, (lprc->left + lprc->right - rcFocus.right) / 2, (lprc->top + lprc->bottom - rcFocus.bottom) / 2); DrawFocusRect(hdc, &rcFocus); } } else { rc = *lprc;
// We should have scroll bars, the text is wider than the window
if (rc.right < lpcml->rc.right) { rc.right = lpcml->rc.right; OffsetRect(&rc, -xHSB, 0); }
DrawText(hdc, lpcml->szCommand, -1, &rc, DT_SINGLELINE | DT_NOPREFIX | DT_CENTER | DT_VCENTER);
if (fFocus) DrawFocusRect(hdc, &rc); }
if (hfont) SelectObject(hdc, hfont); }
/* CmlFixBounds() -
*/ VOID CmlFixBounds( LPCML lpcml ) { HDC hdc; HFONT hfont;
// Figure out how large the text region will be
if (*lpcml->szCommand) { if (hdc = GetWindowDC(ghwndFrame)) { hfont = SelectObject(hdc, ghfontChild);
SetRect(&(lpcml->rc), 0, 0, 20000, 100); DrawText(hdc, lpcml->szCommand, -1, &(lpcml->rc), DT_CALCRECT | DT_WORDBREAK | DT_NOPREFIX | DT_SINGLELINE);
if (hfont) SelectObject(hdc, hfont);
ReleaseDC(ghwndFrame, hdc); } } else { SetRect(&(lpcml->rc), 0, 0, 0, 0); }
PostMessage(ghwndPane[CONTENT], WM_FIXSCROLL, 0, 0L); }
/* CmlReadFromNative() - Read a command line object from the native data.
*/ LPCML CmlReadFromNative( LPSTR *lplpstr ) { BOOL fCmdIsLink; WORD w; CHAR szCmd[CBCMDLINKMAX];
MemRead(lplpstr, (LPSTR)&w, sizeof(WORD)); fCmdIsLink = (BOOL)w; StringCchCopy(szCmd, ARRAYSIZE(szCmd), *lplpstr); *lplpstr += lstrlen(szCmd) + 1;
return CmlCreate(szCmd, fCmdIsLink); }
/* CmlWriteToNative() - Write a command line object to the native data.
*/ DWORD CmlWriteToNative( LPCML lpcml, LPSTR *lplpstr ) { WORD w;
if (lplpstr) { w = (WORD)lpcml->fCmdIsLink; MemWrite(lplpstr, (LPSTR)&w, sizeof(WORD)); MemWrite(lplpstr, (LPSTR)lpcml->szCommand, lstrlen(lpcml->szCommand) + 1); }
return sizeof(WORD) + lstrlen(lpcml->szCommand) + 1; }
|