Code/Resource
Windows Develop
Linux-Unix program
Internet-Socket-Network
Web Server
Browser Client
Ftp Server
Ftp Client
Browser Plugins
Proxy Server
Email Server
Email Client
WEB Mail
Firewall-Security
Telnet Server
Telnet Client
ICQ-IM-Chat
Search Engine
Sniffer Package capture
Remote Control
xml-soap-webservice
P2P
WEB(ASP,PHP,...)
TCP/IP Stack
SNMP
Grid Computing
SilverLight
DNS
Cluster Service
Network Security
Communication-Mobile
Game Program
Editor
Multimedia program
Graph program
Compiler program
Compress-Decompress algrithms
Crypt_Decrypt algrithms
Mathimatics-Numerical algorithms
MultiLanguage
Disk/Storage
Java Develop
assembly language
Applications
Other systems
Database system
Embeded-SCM Develop
FlashMX/Flex
source in ebook
Delphi VCL
OS Develop
MiddleWare
MPI
MacOS develop
LabView
ELanguage
Software/Tools
E-Books
Artical/Document
printobj.c
Package: shell.rar [view]
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 16k
Category:
Windows Kernel
Development Platform:
Visual C++
- #include "shellprv.h"
- #pragma hdrstop
- #include "printer.h"
- typedef struct tagPREVPRINTER
- {
- TCHAR szPrinterName[MAXNAMELENBUFFER];
- HWND hwndStub;
- } PREVPRINTER, *LPPREVPRINTER;
- int FindPrinter(HDSA hPrevPrinters, LPCTSTR lpszPrinterName)
- {
- int i = -1;
- if (hPrevPrinters)
- {
- for (i=DSA_GetItemCount(hPrevPrinters)-1; i>=0; --i)
- {
- LPPREVPRINTER pPrevPrinter = DSA_GetItemPtr(hPrevPrinters, i);
- if (lstrcmpi(pPrevPrinter->szPrinterName, lpszPrinterName) == 0)
- {
- break;
- }
- }
- }
- return(i);
- }
- //
- // if uAction IS NOT MSP_NEWDRIVER then:
- // installs a printer (uAction). If successful, notifies the shell and
- // returns a pidl to the printer. ILFree() is callers responsibility.
- // otherwise, if uAction IS MSP_NEWDRIVER then:
- // installs a printer driver (uAction). If successful, fills the new
- // driver's name into lpBuffer (ASSUMED >= MAXNAMELEN).
- // Always returns NULL.
- // if uAction is MSP_TESTPAGEPARTIALPROMPT then:
- // executes the test page code
- // Always returns NULL.
- //
- HWND hwndPrinterSetup = NULL; // active printer setup window, if any
- LPITEMIDLIST Printers_PrinterSetup(HWND hwndStub, UINT uAction, LPTSTR lpBuffer, LPCTSTR pszServer)
- {
- #ifndef WINNT // PRINTQ
- HINSTANCE hmMSPrint;
- PRINTERSETUPPROC32 pfnPrinterSetup;
- #endif
- LPITEMIDLIST pidl = NULL;
- //
- // HACK! This hack is related to BUG #272207
- // This function is called from Printers_DeletePrinter for
- // printer deletion and this case we should not check
- // for REST_NOPRINTERADD restriction.
- //
- // -LazarI
- //
- if (MSP_NEWPRINTER == uAction ||
- MSP_NETPRINTER == uAction ||
- MSP_NEWPRINTER_MODELESS == uAction)
- {
- if (SHIsRestricted(hwndStub, REST_NOPRINTERADD))
- {
- return NULL;
- }
- }
- #ifndef WINNT
- //
- // Windows 95 permits a user to printer a test page from the help trouble
- // shooter, with out any contextual information. i.e. a printer has
- // not been selected. In this case they will prompt the user for a
- // printer from a list of printers. In Windows NT we do not support
- // printing a test page from the help trouble shooter.
- //
- // In Windows NT we prevent multiple add printer wizards from within
- // the bPrinterSetup API located in printui.dll, where as Windows 95
- // prevents multiple add printer wizards here using a global.
- // we only want one PrinterSetup window up at a time
- //
- if (uAction != MSP_TESTPAGEPARTIALPROMPT)
- {
- BOOL fRet = FALSE;
- HWND hwnd;
- ENTERCRITICAL;
- if (hwndPrinterSetup != NULL &&
- SetForegroundWindow(
- hwnd = GetLastActivePopup(hwndPrinterSetup) ))
- {
- fRet = TRUE;
- }
- else
- {
- hwndPrinterSetup = hwndStub;
- }
- LEAVECRITICAL;
- if (fRet)
- {
- // In the case of deleting a printer, it is very unclear
- // why the "install wizard" popped up into the user's face.
- // Put up a generic "you must complete this operation" message.
- ShellMessageBox(HINST_THISDLL, hwnd,
- MAKEINTRESOURCE(IDS_MUSTCOMPLETE), MAKEINTRESOURCE(IDS_PRINTERS), MB_OK);
- return NULL;
- }
- }
- #endif
- #if WINNT // PRINTQ
- if (1)
- {
- DWORD cchBufLen = 0;
- #else
- hmMSPrint = LoadLibrary(TEXT("MSPRINT2.DLL"));
- if (!ISVALIDHINSTANCE(hmMSPrint))
- {
- DebugMsg(DM_WARNING,TEXT("sh WN - Printers_PrinterSetup could not load MSPRINT2.DLL"));
- ASSERT(FALSE);
- return NULL;
- }
- // BUGBUG: pop up a message box on error?
- pfnPrinterSetup = (PRINTERSETUPPROC32)GetProcAddress(hmMSPrint, "PrinterSetup32");
- if (pfnPrinterSetup)
- {
- WORD cchBufLen = 0;
- #endif // PRINTQ
- LPIDPRINTER pidp;
- if (lpBuffer)
- cchBufLen = lstrlen(lpBuffer) + 1;
- if (cchBufLen < ARRAYSIZE(pidp->cName))
- cchBufLen = ARRAYSIZE(pidp->cName);
- pidp = (void*)LocalAlloc(LPTR, SIZEOF(IDPRINTER) - SIZEOF(pidp->cName) + cchBufLen * SIZEOF(TCHAR));
- if (pidp)
- {
- pidp->cName[0] = TEXT('');
- if (lpBuffer)
- lstrcpy(pidp->cName, lpBuffer);
- //
- // We don't have to worry about PrinterSetup failing due to the
- // output buffer being too small. It's the right size
- // (32 bytes for Win9x, MAXNAMELENBUFFER for WinNT).
- //
- // On Win9x, this is ANSI, on WinNT, setup expects UNICODE.
- //
- // Also, there are no alignment problems since pidp is
- // allocated by us.
- //
- #ifdef WINNT // PRINTQ
- if (bPrinterSetup(hwndStub,LOWORD(uAction),cchBufLen, pidp->cName,&cchBufLen, pszServer))
- {
- #else
- if (pfnPrinterSetup(hwndStub,LOWORD(uAction),cchBufLen,
- (LPBYTE)pidp->cName,&cchBufLen))
- {
- #endif
- if (uAction == MSP_NEWDRIVER)
- {
- ASSERT(lstrlen(pidp->cName) < MAXNAMELEN);
- lstrcpy(lpBuffer, (LPTSTR)(pidp->cName));
- }
- else if (uAction == MSP_TESTPAGEPARTIALPROMPT)
- {
- // nothing to do for this case
- }
- else if (uAction == MSP_REMOVEPRINTER)
- {
- // a bit ugly, but we need to pass back success for this case
- pidl = (LPITEMIDLIST)TRUE;
- }
- #ifdef WINNT
- else if (uAction == MSP_NEWPRINTER_MODELESS)
- {
- // a bit ugly, but we need to pass back success for this case
- pidl = (LPITEMIDLIST)TRUE;
- }
- #endif
- else
- {
- LPITEMIDLIST pidlParent = SHCloneSpecialIDList(NULL, CSIDL_PRINTERS, FALSE);
- if (pidlParent)
- {
- pidp->cb = (USHORT)(FIELD_OFFSET(IDPRINTER,cName) + (lstrlen(pidp->cName) + 1) * SIZEOF(TCHAR));
- *(USHORT *)((LPBYTE)(pidp) + pidp->cb) = 0;
- pidl = ILCombine(pidlParent, (LPCITEMIDLIST)pidp);
- ILFree(pidlParent);
- }
- }
- }
- else
- {
- DebugMsg(DM_TRACE,TEXT("sh TR - PrinterSetup32() failed (%x)"), GetLastError());
- }
- LocalFree((HLOCAL)pidp);
- }
- }
- else
- {
- DebugMsg(DM_ERROR,TEXT("sh ER - GetProcAddress(MSPRINT32.DLL,PrinterSetup32) failed"));
- }
- hwndPrinterSetup = NULL;
- #ifndef WINNT // PRINTQ
- FreeLibrary(hmMSPrint);
- #endif
- return(pidl);
- }
- //
- // Printer_OneWindowAction calls pfn iff it's not in use for printer lpName.
- // If it's already in use for printer lpName, bring focus to that window.
- //
- void Printer_OneWindowAction(HWND hwndStub, LPCTSTR lpName, HDSA *lphdsa, LPFNPRINTACTION pfn, LPARAM lParam, BOOL fModal)
- {
- int i;
- PREVPRINTER sThisPrinter;
- LPPREVPRINTER pPrevPrinter;
- EnterCriticalSection(&g_csPrinters);
- // Initialize the DSA if we need to
- if (!*lphdsa)
- {
- *lphdsa = DSA_Create(SIZEOF(sThisPrinter), 4);
- if (!*lphdsa)
- {
- goto error_exit;
- }
- }
- // Bring window up if lpName is in use
- i = FindPrinter(*lphdsa, lpName);
- if (i >= 0)
- {
- HWND hwnd;
- if (fModal) {
- ShellMessageBox(HINST_THISDLL,
- hwndStub,
- MAKEINTRESOURCE(IDS_CANTOPENMODALPROP),
- MAKEINTRESOURCE(IDS_PRINTERS),
- MB_OK|MB_ICONERROR);
- }
- pPrevPrinter = DSA_GetItemPtr(*lphdsa, i);
- if (pPrevPrinter->hwndStub == NULL ||
- (hwnd = GetLastActivePopup(pPrevPrinter->hwndStub)) == NULL ||
- !ShowWindow(hwnd, SW_SHOW) ||
- !SetForegroundWindow(hwnd) )
- {
- // The window must have crashed before. Remove it from the
- // hdsa and add it again.
- // WARNING: This window could be stuck waiting for a
- // PRINTER_INFO_2 before putting up the window. In this case, the
- // ShowWindow will fail and we'll wind up with two windows up.
- DSA_DeleteItem(*lphdsa, i);
- }
- else
- {
- // We brought the existing window to the front. We're done.
- goto exit;
- }
- }
- // We're bringing up the window
- lstrcpy(sThisPrinter.szPrinterName, lpName);
- sThisPrinter.hwndStub = hwndStub;
- if (DSA_AppendItem(*lphdsa, &sThisPrinter) < 0)
- {
- goto error_exit;
- }
- // Call the printer function. Make sure winspool is loaded
- LeaveCriticalSection(&g_csPrinters);
- pfn(hwndStub, lpName, SW_SHOWNORMAL, lParam);
- EnterCriticalSection(&g_csPrinters);
- // The window is gone
- // (Use sThisPrinter.szPrinterName since it may have been renamed)
- i = FindPrinter(*lphdsa, sThisPrinter.szPrinterName);
- if (i >= 0)
- {
- DSA_DeleteItem(*lphdsa, i);
- // Don't use up memory we don't need
- if (DSA_GetItemCount(*lphdsa) == 0)
- {
- DSA_Destroy(*lphdsa);
- *lphdsa = NULL;
- }
- }
- goto exit;
- error_exit:
- // BUGBUG: do we want to put up an Out Of Memory error?
- DebugMsg(DM_WARNING, TEXT("sh WN - Printer_OneWindowAction() - Out Of Memory"));
- exit:
- LeaveCriticalSection(&g_csPrinters);
- return;
- }
- extern HDSA hdsaPrintDef;
- void PrintDef_UpdateHwnd(LPCTSTR lpszPrinterName, HWND hWnd)
- {
- int i;
- LPPREVPRINTER pThisPrinter;
- EnterCriticalSection(&g_csPrinters);
- if (!hdsaPrintDef)
- {
- goto Error0;
- }
- i = FindPrinter(hdsaPrintDef, lpszPrinterName);
- if (i < 0)
- {
- goto Error0;
- }
- pThisPrinter = DSA_GetItemPtr(hdsaPrintDef, i);
- pThisPrinter->hwndStub = hWnd;
- Error0:
- LeaveCriticalSection(&g_csPrinters);
- }
- void PrintDef_UpdateName(LPCTSTR lpszPrinterName, LPCTSTR lpszNewName)
- {
- int i;
- LPPREVPRINTER pThisPrinter;
- EnterCriticalSection(&g_csPrinters);
- if (!hdsaPrintDef)
- {
- goto Error0;
- }
- i = FindPrinter(hdsaPrintDef, lpszPrinterName);
- if (i < 0)
- {
- goto Error0;
- }
- pThisPrinter = DSA_GetItemPtr(hdsaPrintDef, i);
- lstrcpy(pThisPrinter->szPrinterName, lpszNewName);
- Error0:
- LeaveCriticalSection(&g_csPrinters);
- }
- void PrintDef_RefreshQueue(LPCTSTR lpszPrinterName)
- {
- int i;
- LPPREVPRINTER pThisPrinter;
- EnterCriticalSection(&g_csPrinters);
- if (!hdsaPrintDef)
- {
- goto Error0;
- }
- if (lpszPrinterName)
- {
- i = FindPrinter(hdsaPrintDef, lpszPrinterName);
- if (i < 0)
- {
- goto Error0;
- }
- pThisPrinter = DSA_GetItemPtr(hdsaPrintDef, i);
- SendMessage(pThisPrinter->hwndStub, WM_COMMAND, ID_VIEW_REFRESH, 0L);
- }
- else
- {
- for (i=DSA_GetItemCount(hdsaPrintDef)-1; i>=0; --i)
- {
- pThisPrinter = DSA_GetItemPtr(hdsaPrintDef, i);
- SendMessage(pThisPrinter->hwndStub, WM_COMMAND, ID_VIEW_REFRESH, 0L);
- }
- }
- Error0:
- LeaveCriticalSection(&g_csPrinters);
- }
- //---------------------------------------------------------------------------
- //
- // IDropTarget stuff
- //
- STDMETHODIMP CPrintObjs_DragEnter(IDropTarget *pdt, IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
- {
- CIDLDropTarget *this = IToClass(CIDLDropTarget, dropt, pdt);
- // let the base-class process it now to save away pdwEffect
- CIDLDropTarget_DragEnter(pdt, pDataObj, grfKeyState, pt, pdwEffect);
- // We allow files to be dropped for printing
- // if it is from the bitbucket only DROEFFECT_MOVE will be set in *pdwEffect
- // so this will keep us from printing wastbasket items.
- if (this->dwData & DTID_HDROP)
- *pdwEffect &= DROPEFFECT_COPY;
- else
- *pdwEffect = DROPEFFECT_NONE; // Default action is nothing
- this->dwEffectLastReturned = *pdwEffect;
- return S_OK;
- }
- void Printer_PrintHDROPFiles(HWND hwnd, HDROP hdrop, LPCITEMIDLIST pidlPrinter)
- {
- DRAGINFO di;
- di.uSize = SIZEOF(di);
- if (DragQueryInfo(hdrop, &di))
- {
- LPTSTR lpFileName = di.lpFileList;
- int i = IDYES;
- // Printing more than one file at a time can easily fail.
- // Ask the user to confirm this operation.
- if (*lpFileName && *(lpFileName + lstrlen(lpFileName) + 1))
- {
- i = ShellMessageBox(HINST_THISDLL,
- NULL,
- MAKEINTRESOURCE(IDS_MULTIPLEPRINTFILE),
- MAKEINTRESOURCE(IDS_PRINTERS),
- MB_YESNO|MB_ICONINFORMATION);
- }
- if (i == IDYES)
- {
- // BUGBUG: It would be really nice to have a progress bar when
- // printing multiple files. And there should definitely be a way
- // to cancel this operation. Oh well, we warned them...
- while (*lpFileName != TEXT(''))
- {
- Printer_PrintFile(hwnd, lpFileName, pidlPrinter);
- lpFileName += lstrlen(lpFileName) + 1;
- }
- }
- SHFree(di.lpFileList);
- }
- }
- void FreePrinterThreadParam(PRNTHREADPARAM *pthp)
- {
- if (pthp->pDataObj)
- pthp->pDataObj->lpVtbl->Release(pthp->pDataObj);
- if (pthp->pstmDataObj)
- pthp->pstmDataObj->lpVtbl->Release(pthp->pstmDataObj);
- ILFree(pthp->pidl);
- LocalFree((HLOCAL)pthp);
- }
- //
- // This is the entry of "drop thread"
- //
- DWORD CALLBACK CPrintObj_DropThreadProc(void *pv)
- {
- PRNTHREADPARAM *pthp = (PRNTHREADPARAM *)pv;
- STGMEDIUM medium;
- FORMATETC fmte = {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
- CoGetInterfaceAndReleaseStream(pthp->pstmDataObj, &IID_IDataObject, (void **)&pthp->pDataObj);
- pthp->pstmDataObj = NULL;
- if (pthp->pDataObj && SUCCEEDED(pthp->pDataObj->lpVtbl->GetData(pthp->pDataObj, &fmte, &medium)))
- {
- Printer_PrintHDROPFiles(pthp->hwnd, medium.hGlobal, pthp->pidl);
- ReleaseStgMedium(&medium);
- }
- FreePrinterThreadParam(pthp);
- return 0;
- }
- HRESULT PrintObj_DropPrint(IDataObject *pDataObj, HWND hwnd, DWORD dwEffect, LPCITEMIDLIST pidl, LPTHREAD_START_ROUTINE pfn)
- {
- HRESULT hres;
- PRNTHREADPARAM *pthp = (PRNTHREADPARAM *)LocalAlloc(LPTR, SIZEOF(*pthp));
- if (pthp)
- {
- CoMarshalInterThreadInterfaceInStream(&IID_IDataObject, (IUnknown *)pDataObj, &pthp->pstmDataObj);
- pthp->hwnd = hwnd;
- pthp->dwEffect = dwEffect;
- pthp->pidl = ILClone(pidl);
- if (hwnd)
- ShellFolderView_GetAnchorPoint(hwnd, FALSE, &pthp->ptDrop);
- if (SHCreateThread(pfn, pthp, CTF_COINIT, NULL))
- {
- hres = S_OK;
- }
- else
- {
- FreePrinterThreadParam(pthp);
- hres = E_OUTOFMEMORY;
- }
- }
- return hres;
- }
- STDMETHODIMP CPrintObjs_DropCallback(IDropTarget *pdt, IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect, LPTHREAD_START_ROUTINE pfn)
- {
- CIDLDropTarget *this = IToClass(CIDLDropTarget, dropt, pdt);
- HRESULT hres;
- *pdwEffect = this->dwEffectLastReturned;
- if (*pdwEffect)
- hres = CIDLDropTarget_DragDropMenu(this, DROPEFFECT_COPY, pDataObj,
- pt, pdwEffect, NULL, NULL, MENU_PRINTOBJ_DD, grfKeyState);
- else
- hres = S_FALSE;
- if (*pdwEffect)
- hres = PrintObj_DropPrint(pDataObj, this->hwndOwner, *pdwEffect, this->pidl, pfn);
- CIDLDropTarget_DragLeave(pdt);
- return hres;
- }
- STDMETHODIMP CPrintObjs_Drop(IDropTarget *pdt, IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
- {
- return CPrintObjs_DropCallback(pdt, pDataObj, grfKeyState, pt, pdwEffect, CPrintObj_DropThreadProc);
- }
- const IDropTargetVtbl c_CPrintObjsDropTargetVtbl =
- {
- CIDLDropTarget_QueryInterface, CIDLDropTarget_AddRef, CIDLDropTarget_Release,
- CPrintObjs_DragEnter,
- CIDLDropTarget_DragOver,
- CIDLDropTarget_DragLeave,
- CPrintObjs_Drop,
- };