|
|
/*---File: printman.c ----------------------------------------------------
* * Description: * NT Print Manager main function and Window Procedures. * * This document contains confidential/proprietary information. * Copyright (c) 1990-1992 Microsoft Corporation, All Rights Reserved. * * Revision History: * [00] 21-Nov-90 stevecat created * [01] 03-Jan-91 stevecat Modified to use Windows MDI * [02] 25-Mar-91 stevecat Modified to use NT WINSPOOL APIs * [03] 13-Jan-92 stevecat New PrintMan UI * * March 1992 + andrewbe Completely updated and new function added * * ---------------------------------------------------------------------- */
/* =========================================================================
Header files ========================================================================= */ /* Application-specific */
#include "printman.h"
#include <lmcons.h>
#include <lmerr.h>
#include <uiexport.h>
#include <stdarg.h>
#include <winuserp.h>
#include <shellapi.h>
#include <stddef.h>
/* ========================================================================
Definitions ======================================================================== */
#define ISF_NAME 0
#define ISF_STATUS 1
#define ISF_WAITING 2
#define SF_COUNT 3
#define SW2WS( sw ) \
( sw == SW_SHOWMINIMIZED ? WS_MINIMIZE \ : sw == SW_SHOWMAXIMIZED ? WS_MAXIMIZE \ : 0 )
#define INIVALUES 8
#define RECTSIDES 4
#define OPTION_NOTOOLBAR 0x00000001
#define OPTION_NOSTATUSBAR 0x00000002
#define OPTION_NOSAVESETTINGS 0x00000004
/* Define our own IDs for menu popups, since USER doesn't:
*/ #define POPUP_PRINTER 0
#define POPUP_DOCUMENT 1
#define POPUP_OPTIONS 2
#define POPUP_SECURITY 3
#define POPUP_WINDOW 4
#define POPUP_HELP 5
#define POPUP_COUNT 6
#define GETMDIWIN( hwnd ) \
(PMDIWIN_INFO)GetWindowLong( hwnd, GWL_PMDIWIN )
#define GETCONTEXT( hwnd ) \
( (PMDIWIN_INFO)GetWindowLong( hwnd, GWL_PMDIWIN ) )->pContext
#define GETQUEUE( hwnd ) \
(PQUEUE)( (PMDIWIN_INFO)GetWindowLong( hwnd, GWL_PMDIWIN ) )->pContext
#define GETCOLUMN(hwnd) \
( (PMDIWIN_INFO)GetWindowLong( hwnd, GWL_PMDIWIN ) )->pColumns
#define STATUS_MODE_NORMAL 0
#define STATUS_MODE_HELP 1
#define WM_INIT_PRINTER_WINDOWS WM_USER+0xa
#define WM_INIT_SERVER_WINDOWS WM_USER+0xb
#define WM_REG_NOTIFY_CHANGE_KEY_VALUE WM_USER+0xc
/*
* Declarations for external calls * ------------------------------- */
/* ========================================================================
Structures and Typedefs ======================================================================== */
typedef struct _SAVEDWINDOWPOS { int left; int top; int width; int height; int xicon; int yicon; int sw; DWORD options; } SAVEDWINDOWPOS, *PSAVEDWINDOWPOS;
typedef struct _REGISTRY_DATA { WINDOWPLACEMENT WindowPlacement; DWORD Options; INT Headers[ANYSIZE_ARRAY]; } REGISTRY_DATA, *PREGISTRY_DATA;
/* ==========================================================================
Global Data ========================================================================== */ #if DBG
DWORD GLOBAL_DEBUG_FLAGS = DBG_ERROR | DBG_WARNING | DBG_BREAK_ON_ERROR; #endif
TCHAR szPrintManagerClass[] = TEXT("Print Manager Frame"); TCHAR szMenuClass[] = TEXT("PrintManMenu"); // This must match the name in res.rc
TCHAR szChildClass[] = TEXT("Printer MDI Child");
// External functions
BOOL RegisterArrowClass (HANDLE hModule);
// Data
TCHAR szNtLanMan[] = TEXT("NTLANMAN"); CHAR szI_SystemFocusDialog[] = "I_SystemFocusDialog"; BOOL bToolBar; BOOL bStatusBar; BOOL bSaveSettings; //TCHAR szStatusBar[] = TEXT("StatusBar");
int dyBorder; /* System Border Width/Height */ int dyBorderx2; /* System Border Width/Height * 2 */ //int dyStatus; /* Status Bar height */
int dxStatusField; int dxStatPrtField; // Width of strStatusName text box
int dxStatProgField; // Width of strStatusStatus text box
int dxStatQueField; // Width of strStatusWaiting text box
DWORD cx, cy; // Average char width/height - default font
int dxDefaultLabel; int dyDefaultLabel;
HBITMAP hbmBitmaps = NULL; HBITMAP hbmDefault = NULL; HBITMAP hbmMasks = NULL; HDC hdcMem = NULL; HDC hdcMasks = NULL;
HFONT hfontHelv; HFONT hfontHelvBold;
TCHAR szHelv[] = TEXT("MS Shell Dlg"); TCHAR sz8[] = TEXT("8"); TCHAR sz10[] = TEXT("10"); TCHAR szNULL[] = TEXT("");
TCHAR szTitleFormat[] = TEXT("%s - %s"); TCHAR szPrintManHlp[] = TEXT("PRINTMAN.HLP"); WCHAR szLPrintManHlp[] = L"PRINTMAN.HLP";
DWORD SysColorHighlight; DWORD SysColorHighlightText; DWORD SysColorWindow; DWORD SysColorWindowText; DWORD SysColorBtnFace; DWORD SysColorBtnText; DWORD SysColorBtnHighlight; DWORD SysColorBtnShadow; DWORD SysColorWindowFrame;
TCHAR szInternational[] = TEXT("intl"); BOOL TwentyFourHourClock;
// JAPAN v-hirot July.07.1993 for New Prefix
// TimePrefix is for Japanese usage - krishnag
BOOL TimePrefix;
// CountryCode - krishnag Sept 1, 1993
// We have a two code paths; one for Japan; one for the rest of the world
BOOL bJapan;
TCHAR szTimeSep[TIMESEP_LENGTH]; TCHAR szAMPM[2][AMPM_LENGTH]; BOOL TimeFormatLeadingZero; BOOL MetricMeasurement; TCHAR szDecimalPoint[2]; DWORD DecimalDigits; DWORD LeadingZero; TCHAR szSizeFormat[14];
UINT WM_Help = 0; UINT WM_DragList = 0; HKEY hPrinterKey; // Per User Registry Printer Key
TCHAR *szRegistryPrinter=TEXT("Printers");
HWND hwndStatus;
DWORD WinHelpMenuID = 0; /* Global set in response to WM_MENUSELECT */
/* Set this before we call AddPrinter, so that we don't need to do anything
* when LocalServerThread posts us a WM_PRINTER_ADDED message: */ BOOL PrinterAdded = FALSE;
HANDLE hLocalServer;
extern HANDLE ThreadMessageRead; extern HANDLE ThreadMessageWritten; extern MSG ThreadMessage;
/* ==========================================================================
Local Data ========================================================================== */
TEXTMETRIC tm;
COLUMN MDIPrinterDefaultColumn[MDIHEAD_JOB_COUNT]; COLUMN MDIServerDefaultColumn[MDIHEAD_PRINTER_COUNT]; int HeaderHeight;
/* Minimum number of 'X' character widths for the columns:
*/ INT MDIPrinterMinimumCharacterWidth[] = { 12, 20, 0, 0, 0, 0, 0 }; INT MDIServerMinimumCharacterWidth[] = { 25, 0, 0, 20, 30 };
HCURSOR hcursorArrow; HCURSOR hcursorReorder; HCURSOR hcursorWait;
HICON hiconPrinter; HICON hiconServer; HICON hiconConnect; HICON hiconShared;
//HHOOK hhookMessage;
HHOOK hhookGetMsg;
TCHAR szRegPrinters[] = TEXT("Printers"); TCHAR szRegServers[] = TEXT("Servers");
//
// Lowercase, like win31.
//
PTCHAR szWindows = TEXT("windows"); PTCHAR szDevices = TEXT("devices"); PTCHAR szDevice = TEXT("device");
REGISTRY_ENTRY RegistryEntries = { REG_BINARY, sizeof(REGISTRY_DATA) };
WNDPROC DefListboxWndProc;
/* Handles of the popup menus needed to put up help in the status bar
* in response to menu selections. (Popups don't have IDs, unfortunately.) */ HMENU hmenuPopups[POPUP_COUNT];
DWORD pMenuHelpIDs[] = { 0, 0, IDS_HELPPRINTER, POPUP_PRINTER, IDS_HELPDOCUMENT, POPUP_DOCUMENT, IDS_HELPOPTIONS, POPUP_OPTIONS, IDS_HELPSECURITY, POPUP_SECURITY, IDS_HELPWINDOW, POPUP_WINDOW, IDS_HELPHELP, POPUP_HELP };
BOOL NetworkInstalled = FALSE;
/* Global hack so we can ignore registry change notification
* when it was brought about by our own actions: */ BOOL ExpectingNotifyChangeKeyValue = FALSE;
/* ==========================================================================
Local Function Declarations ========================================================================== */
LONG FrameCreate(HWND hWnd, LPCREATESTRUCT pCreateStruct); VOID GetSystemColors( VOID ); BOOL UserHasNetworkAccess( VOID ); VOID RemoveNetworkMenuItems( HWND hwnd ); BOOL NetworkIsInstalled( VOID ); VOID SetStatusMode( int Mode, BOOL Update ); LONG FrameThreadError(HWND hWnd, PMDIWIN_INFO pMDIWinInfo, DWORD dwError); LONG FrameInitMenu(HWND hWnd); LONG FrameMenuSelect( HWND hwnd, WPARAM wParam, LPARAM lParam ); LONG FramePaint(HWND hWnd); VOID FrameSize(HWND hWnd, WPARAM Type, long Dimensions); VOID FrameClose(HWND hWnd); VOID FrameHelp(HWND hwnd, UINT HelpID); VOID SaveWindowPos( HWND hwnd, DWORD Options, BOOL MDIWindow ); LONG FrameCommandConnectToPrinter(HWND hWnd); //LONG FrameCommandRemoveConnection(HWND hWnd);
LONG FrameCommandCreatePrinter(HWND hWnd); LONG FrameCommandProperties(HWND hWnd); LONG FrameCommandDeletePrinter(HWND hWnd); LONG FrameCommandDeletePrinterHelper(HWND hWnd, HWND hwndMDI, BOOL bConfirm); BOOL DeleteLocalPrinter(HWND hwnd, HWND hwndMDI, PQUEUE pQueue, BOOL bConfirm); BOOL DeleteRemotePrinter(HWND hwnd, PSERVER_CONTEXT pServerContext, BOOL bConfirm); BOOL DeleteConnection(HWND hWnd, HWND hwndMDI, PQUEUE pQueue, BOOL bConfirm); HWND FindPrinterWindow( LPTSTR pPrinterName ); LONG FrameCommandPrinterPauseResume(HWND hWnd, BOOL bPause); //BOOL SetPrinterTitle( HWND hwnd, PTCHAR pPrinterName, DWORD Status );
BOOL SetMDITitle( HWND hwnd, PMDIWIN_INFO pInfo ); LONG FrameCommandPurgePrinter(HWND hWnd); LONG FrameCommandForms(HWND hWnd); LONG FrameCommandServerViewer(HWND hWnd); LONG FrameCommandChangePrinter(HWND hWnd); LONG FrameCommandRemoveDoc(HWND hWnd); LONG FrameCommandDocDetails(HWND hWnd); LONG FrameCommandDocumentPauseResume(HWND hWnd, WORD PauseResume); LONG FrameCommandRestart(HWND hWnd); LONG FrameCommandFont(HWND hWnd); LONG FrameCommandRefreshRate(HWND hWnd); LONG FrameCommandToolbar(HWND hWnd); LONG FrameCommandStatusbar(HWND hWnd); LONG FrameCommandSaveSettings(HWND hWnd); LONG FrameCommandPermissions(HWND hWnd); LONG FrameCommandAuditing(HWND hWnd); LONG FrameCommandOwner(HWND hWnd); LONG FrameCommandClose(HWND hWnd); LONG FrameCommandAbout(HWND hWnd); LONG FrameCommandReturn(); VOID FrameCommandDefaultPrinter(HWND hwnd, WORD Command); VOID FrameCommandToolbarNotify( HWND hwnd, WPARAM wParam, LPARAM lParam ); VOID FrameCommandTab(HWND hwnd); LONG FrameCommandDefault(HWND hWnd, WPARAM wParam, LONG lParam); VOID FrameSysColorChange( VOID ); VOID FrameWinIniChange( HWND hWnd, LPTSTR pSection ); VOID FramePrinterAdded( HWND hwnd, DWORD dwType ); VOID FrameRegNotifyChangeKeyValue( HWND hwnd, HKEY hWindowsKey );
VOID CreateMDIDefaultColumns( HWND hwnd, DWORD cColumns, DWORD idFirstColumn, PCOLUMN pColumns, PINT pDefaultWidths ); PMDIWIN_INFO CreateQueueWindowInfo( PQUEUE pQueue, PINT pHeaders ); DWORD CALLBACK CreateServerWindow( HWND hwnd, LPTSTR pServerName, HANDLE hServer ); PMDIWIN_INFO CreateServerWindowInfo( PSERVER_CONTEXT pContext, PINT pHeaders ); BOOL InitServerChildWindows( HWND hWnd ); VOID FormatData( PBYTE pData, int Datatype, LPTSTR string ); int GetPrinterStatusString( DWORD Status, LPTSTR string ); VOID MDICreate( HWND hWnd, LONG lParam ); VOID SetDefaultColumnWidths( HWND hwnd, PMDIWIN_INFO pMDIWinInfo, PINT pColumnWidths ); LONG MDIPaint(HWND hwnd, WPARAM wParam, LPARAM lParam); BOOL MDIEraseBkgnd(HWND hwnd, HDC hdc); HICON MDIQueryDragIcon(HWND hwnd); LONG MDIMenuSelect( HWND hwnd, WPARAM wParam, LPARAM lParam ); VOID MDICommandObjListSelChange( HWND hwnd ); VOID SetObjectSelection( PMDIWIN_INFO pInfo, DWORD Selection ); VOID MDICommandObjListDblClk( HWND hwnd ); VOID MDICommandHeaderBeginDrag( HWND hwnd, PPOINT pCursorPos ); VOID MDICommandHeaderDragging( HWND hwnd, PPOINT pCursorPos, HD_NOTIFY * lpNot ); VOID MDICommandHeaderEndDrag( HWND hwnd, PPOINT pCursorPos, HD_NOTIFY * lpNot ); VOID InvertDragMark( HWND hwnd, PPOINT pCursorPos ); VOID UpdateColumns( HWND hwnd, HD_NOTIFY * lpNot ); BOOL MDIClose( HWND hwnd ); VOID MDIVKeyToItemSpace( HWND hwnd ); VOID MDIParentNotifyRButtonDown( HWND hwnd, DWORD CursorPos ); VOID MDIVKeyToItemDefault( HWND hwnd ); int MDIVKeyToItemUpDown( HWND hwnd, WORD VKey ); VOID ReorderJob( HWND hwnd, PMDIWIN_INFO pInfo, DWORD Position ); VOID RepaintListboxItem( HWND hwndListbox, DWORD ItemID ); VOID MDISize( HWND hWnd, DWORD Coordinates ); LONG MDIMDIActivate( HWND hwnd, HWND hwndDeactivate, HWND hwndActivate ); VOID MDINCActivate( HWND hwnd ); LONG MDIWindowPosChanged( HWND hwnd, WPARAM wParam, LPARAM lParam ); VOID ClearDragPosition( PMDIWIN_INFO pInfo ); VOID MDISetFocus( HWND hwnd ); VOID MDIMeasureItem( HWND hwnd, LPMEASUREITEMSTRUCT pmis ); VOID MDIDrawItem( HWND hwnd, LPDRAWITEMSTRUCT pdis ); VOID MDITimer( HWND hWnd ); VOID MDIStatusChanged( HWND hwnd ); VOID MDIUpdateList( HWND hwnd ); VOID MDISetParts( HWND hwnd, WPARAM wParam, LPARAM lParam ); VOID MDIDestroy( HWND hwnd ); LONG MDIDragList( HWND hwnd, LPDRAGLISTINFO pDragListInfo );
BOOL RefreshServerContext( PVOID pContext, PDWORD pFlags );
BOOL GetSavedWindowPos( LPTSTR pKey, LPTSTR WindowName, PSAVEDWINDOWPOS pswp, DWORD cHeaders, PINT pHeaders ); UINT GetCurrentMenuItemID( HMENU hMenu );
LONG SubclassListboxWndProc( HWND hWnd, UINT message, WPARAM wParam, LONG lParam );
VOID KillMDIWinInfo( PMDIWIN_INFO pInfo);
/* Copied from winfile:
*/ INT GetHeightFromPointsString( LPTSTR szPoints) { HDC hdc; INT height;
hdc = GetDC(NULL); height = MulDiv(-_tcstol(szPoints, NULL, 10), GetDeviceCaps(hdc, LOGPIXELSY), 72); ReleaseDC(NULL, hdc);
return height; }
/* InitializeInternationalTimeConstants
* * Called to set up the following global variables: * * TwentyFourHourClock - Boolean indicating whether 12- or 24-hour clock * is currently in force. * * MetricMeasurement - Metres or feet and inches (TRUE == metric) * * szTimeSep - Separator for time string - usually ":", unless you're in * Scandinavia, Croatia or a couple of other places. * * szAMPM - Array of 2 strings - usually "AM" or "PM" for 12-hour clock. * * TimeFormatLeadingZero */ VOID InitializeInternationalTimeConstants( VOID ) { LCID lcid; WCHAR Buffer[128];
TwentyFourHourClock = GetProfileInt (szInternational, TEXT("iTime"), 0);
// JAPAN
// V-Hirot July.07.1993 for New Prefix
// krishnag Sept 1, 1993 CountryCode
if (bJapan) { TimePrefix = GetProfileInt (szInternational, TEXT("iTimePrefix"), 0); }
GetProfileString (szInternational, TEXT("sTime"), TEXT(":"), szTimeSep, TIMESEP_LENGTH);
GetProfileString (szInternational, TEXT("s1159"), TEXT("AM"), szAMPM[AM], AMPM_LENGTH); GetProfileString (szInternational, TEXT("s2359"), TEXT("PM"), szAMPM[PM], AMPM_LENGTH);
TimeFormatLeadingZero = (BOOL)GetProfileInt (szInternational, TEXT("iTLZero"), 1);
MetricMeasurement = !((BOOL)GetProfileInt (szInternational, TEXT("iMeasure"), 0)); GetProfileString (szInternational, TEXT("sDecimal"), TEXT("."), szDecimalPoint, sizeof szDecimalPoint/sizeof(TCHAR));
DecimalDigits = GetProfileInt (szInternational, TEXT("iDigits"), 2); LeadingZero = GetProfileInt (szInternational, TEXT("iLzero"), 1);
lcid = GetThreadLocale();
ThousandSeparator = TEXT(','); if (GetLocaleInfoW (lcid, LOCALE_STHOUSAND, Buffer, sizeof Buffer /sizeof(WCHAR))) { ThousandSeparator = Buffer[0]; }
}
HWND CreateQueueWindow( HWND hWnd, PQUEUE pQueue, DWORD Status, DWORD WindowType, DWORD Flags ) { TCHAR Title[80]; TCHAR StatusString[40]; SAVEDWINDOWPOS swp; MDICREATESTRUCT mdicreate; INT pHeaders[MDIHEAD_JOB_COUNT]; INT i;
if (!pQueue) return NULL;
/* Now create a window for this queue. Note that during this function
* the WM_CREATE message is sent to the QueueWinProc but, the Extra * Window Word has not yet been set to hQueue value because we need * the window handle in order to set this value. In order to get * around this 'Catch-22' situation, we pass the hQueue value as the * 'lpParam' value in the MDICREATESTRUCT. Then we only have to be * a little sly when processing the WM_CREATE message to retrieve the * Queue handle. Also, we then set the Window Word value to hQueue * during WM_CREATE message processing, thereby insuring that it will * be available for all subsequent messages. */
if( !GetSavedWindowPos( szRegPrinters, pQueue->pPrinterName, &swp, ( sizeof pHeaders / sizeof *pHeaders ), pHeaders ) ) { /* If no window positions saved, set the column widths to default.
* They will be initialised on MDI creation, since they depend * on the width of the window: */ for( i = 0; i < MDIHEAD_JOB_COUNT; i++ ) pHeaders[i] = CW_USEDEFAULT; }
if( Flags & CREATE_PRINTER_ICONIC ) swp.sw = SW_SHOWMINIMIZED;
if( Status ) { GetPrinterStatusString( Status, StatusString ); _stprintf( Title, szTitleFormat, pQueue->pPrinterName, StatusString ); } else _tcscpy( Title, pQueue->pPrinterName );
if( !(pQueue->pMDIWinInfo = CreateQueueWindowInfo( pQueue, pHeaders ) ) ) return NULL;
pQueue->pMDIWinInfo->Status = Status;
SetWindowTypeIcon(pQueue, WindowType, Flags);
mdicreate.szClass = szChildClass; mdicreate.szTitle = Title; mdicreate.hOwner = hInst; mdicreate.x = swp.left; mdicreate.y = swp.top; mdicreate.cx = swp.width; mdicreate.cy = swp.height; mdicreate.style = SW2WS( swp.sw ) | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; mdicreate.lParam = (LONG)pQueue->pMDIWinInfo;
hWnd = (HWND)SendMessage(hwndClient, WM_MDICREATE, 0, (LONG)&mdicreate);
return hWnd; }
/*
* */ PMDIWIN_INFO CreateQueueWindowInfo( PQUEUE pQueue, PINT pHeaders ) { PMDIWIN_INFO pInfo; PCOLUMN pColumns; int i;
pInfo = (PMDIWIN_INFO)AllocSplMem( sizeof( MDIWIN_INFO ) );
if( !pInfo ) return NULL;
pColumns = (PCOLUMN)AllocSplMem( sizeof( COLUMN ) * MDIHEAD_JOB_COUNT );
if( !pColumns ) { FreeSplMem( pInfo ); return NULL; }
for( i = 0; i < MDIHEAD_JOB_COUNT; i++ ) { pColumns[i].Width = pHeaders[i]; pColumns[i].Text = MDIPrinterDefaultColumn[i].Text; }
/* Initialize all pColumns elements here. Rememberthat some
printers can generate their own error messages which are pointed to by JOB_INFO_2's pStatus field. We have to query each time we display status info as to which field is providing the Status information */
pColumns[MDIHEAD_JOB_STATUS ].Offset = offsetof( JOB_INFO_2, Status ); pColumns[MDIHEAD_JOB_DOCNAME ].Offset = offsetof( JOB_INFO_2, pDocument ); pColumns[MDIHEAD_JOB_OWNER ].Offset = offsetof( JOB_INFO_2, pUserName ); pColumns[MDIHEAD_JOB_PRINTEDAT].Offset = offsetof( JOB_INFO_2, Submitted ); pColumns[MDIHEAD_JOB_PAGES ].Offset = offsetof( JOB_INFO_2, TotalPages ); pColumns[MDIHEAD_JOB_SIZE ].Offset = offsetof( JOB_INFO_2, Size ); pColumns[MDIHEAD_JOB_PRIORITY ].Offset = offsetof( JOB_INFO_2, Priority );
pColumns[MDIHEAD_JOB_STATUS ].Datatype = MDIDATA_JOB_STATUS; pColumns[MDIHEAD_JOB_DOCNAME ].Datatype = MDIDATA_PSZ_UNTITLED_IF_NULL; pColumns[MDIHEAD_JOB_OWNER ].Datatype = MDIDATA_PSZ; pColumns[MDIHEAD_JOB_PRINTEDAT].Datatype = MDIDATA_TIME; pColumns[MDIHEAD_JOB_PAGES ].Datatype = MDIDATA_DWORD_BLANK_IF_ZERO; pColumns[MDIHEAD_JOB_SIZE ].Datatype = MDIDATA_SIZE; pColumns[MDIHEAD_JOB_PRIORITY ].Datatype = MDIDATA_DWORD_BLANK_IF_ZERO;
pInfo->WindowType = MDIWIN_PRINTER; pInfo->hwndList = NULL; pInfo->cNumLines = 0; pInfo->ppData = (PBYTE *)&pQueue->pJobs; pInfo->DataSize = sizeof( JOB_INFO_2 ); pInfo->pcObjects = &pQueue->cJobs; pInfo->cColumns = MDIHEAD_JOB_COUNT; pInfo->pColumns = pColumns; pInfo->IconStatus = offsetof( JOB_INFO_2, Status ); pInfo->pSelObjId = &pQueue->SelJobId; pInfo->ppSelData = (PBYTE *)&pQueue->pSelJob; pInfo->IdOffset = offsetof( JOB_INFO_2, JobId ); pInfo->pFirstEnumObj = &pQueue->FirstEnumJob; pInfo->pcEnumObjs = &pQueue->cEnumJobs; pInfo->DataMutex = CreateMutex( NULL, FALSE, NULL ); #ifdef SEP_WAITHANDLE
pInfo->phWaitObject = &pQueue->hPrinterWait; pInfo->phMain = &pQueue->hPrinter; #else
pInfo->phWaitObject = &pQueue->hPrinter; #endif
pInfo->WaitFlags = PRINTER_CHANGE_PRINTER | PRINTER_CHANGE_JOB; pInfo->pfnRefresh = (REFRESHPROC)GetJobs; pInfo->pfnCheckQuit = (CHECKQUITPROC)CheckQuitQueue; pInfo->pfnInitThread = (INITTHREADPROC)InitQueueThread; // pInfo->SuspendRefresh = FALSE;
pInfo->RefreshSignal = CreateEvent( NULL, EVENT_RESET_MANUAL, EVENT_INITIAL_STATE_SIGNALED, NULL ); if( pInfo->RefreshSignal == NULL ) DBGMSG( DBG_WARNING, ( "CreateEvent failed: Error %d\n", GetLastError( ) ) ); pInfo->pContext = pQueue;
return pInfo; }
//
// Create the server window.
//
// If hServer is NULL, we haven't tried the OpenPrinter yet.
// If hServer is (HANDLE)-1, we tried and failed due to access denied.
// else hServer is valid. InitServerWindowThread picks up these values.
//
DWORD CALLBACK CreateServerWindow( HWND hwnd, LPTSTR pServerName, HANDLE hServer) { PSERVER_CONTEXT pContext; LPTSTR pServerViewerTitle; TCHAR Title[MAX_PATH+20]; // Enough for server name + "Server: "
SAVEDWINDOWPOS swp; MDICREATESTRUCT mdicreate; INT pHeaders[MDIHEAD_PRINTER_COUNT]; INT i;
pContext = AllocSplMem( sizeof( SERVER_CONTEXT ) );
if (!pContext) { //
// !! LATER !!
// Put up an error
//
return NO_ERROR; }
pContext->pServerName = AllocSplStr( pServerName ); pContext->hServer = hServer;
if( !GetSavedWindowPos( szRegServers, pServerName, &swp, ( sizeof pHeaders / sizeof *pHeaders ), pHeaders ) ) { /* If no window positions saved, set the column widths to default.
* They will be initialised on MDI creation, since they depend * on the width of the window: */ for( i = 0; i < MDIHEAD_PRINTER_COUNT; i++ ) pHeaders[i] = CW_USEDEFAULT; }
pContext->pMDIWinInfo = CreateServerWindowInfo( pContext, pHeaders );
pServerViewerTitle = GetString( IDS_SERVERVIEWERTITLE ); _stprintf( Title, pServerViewerTitle, pServerName );
FreeSplStr( pServerViewerTitle );
mdicreate.szClass = szChildClass; mdicreate.szTitle = Title; mdicreate.hOwner = hInst; mdicreate.x = swp.left; mdicreate.y = swp.top; mdicreate.cx = swp.width; mdicreate.cy = swp.height; mdicreate.style = SW2WS( swp.sw ) | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; mdicreate.lParam = (LONG)pContext->pMDIWinInfo;
SendMessage(hwndClient, WM_MDICREATE, 0, (LONG)&mdicreate);
return NO_ERROR; }
/*
* */ PMDIWIN_INFO CreateServerWindowInfo( PSERVER_CONTEXT pContext, PINT pHeaders) { PMDIWIN_INFO pInfo; PCOLUMN pColumns; int i;
pInfo = (PMDIWIN_INFO)AllocSplMem( sizeof( MDIWIN_INFO ) );
if( !pInfo ) return NULL;
pColumns = (PCOLUMN)AllocSplMem( sizeof( COLUMN ) * MDIHEAD_PRINTER_COUNT );
if( !pColumns ) { FreeSplMem( pInfo ); return NULL; }
for( i = 0; i < MDIHEAD_PRINTER_COUNT; i++ ) { pColumns[i].Width = pHeaders[i]; pColumns[i].Text = MDIServerDefaultColumn[i].Text; }
pColumns[MDIHEAD_PRINTER_PRINTER].Offset = offsetof( PRINTER_INFO_2, pPrinterName ); pColumns[MDIHEAD_PRINTER_STATUS ].Offset = offsetof( PRINTER_INFO_2, Status ); pColumns[MDIHEAD_PRINTER_JOBS ].Offset = offsetof( PRINTER_INFO_2, cJobs ); pColumns[MDIHEAD_PRINTER_PORT ].Offset = offsetof( PRINTER_INFO_2, pPortName ); pColumns[MDIHEAD_PRINTER_TYPE ].Offset = offsetof( PRINTER_INFO_2, pDriverName );
pColumns[MDIHEAD_PRINTER_PRINTER].Datatype = MDIDATA_PSZ; pColumns[MDIHEAD_PRINTER_STATUS ].Datatype = MDIDATA_PRINTER_STATUS; pColumns[MDIHEAD_PRINTER_JOBS ].Datatype = MDIDATA_DWORD; pColumns[MDIHEAD_PRINTER_PORT ].Datatype = MDIDATA_PSZ; pColumns[MDIHEAD_PRINTER_TYPE ].Datatype = MDIDATA_PSZ;
pInfo->WindowType = MDIWIN_SERVER; pInfo->hwndList = NULL; pInfo->cNumLines = 0; pInfo->ppData = (PBYTE *)&pContext->pPrinters; pInfo->DataSize = sizeof( PRINTER_INFO_2 ); pInfo->pcObjects = &pContext->cPrinters; pInfo->cColumns = MDIHEAD_PRINTER_COUNT; pInfo->pColumns = pColumns; pInfo->IconStatus = offsetof( PRINTER_INFO_2, Status ); pInfo->pSelObjId = &pContext->SelPrinterId; pInfo->ppSelData = (PBYTE *)&pContext->pSelPrinter; pInfo->IdOffset = offsetof( PRINTER_INFO_2, pPrinterName ); pInfo->pFirstEnumObj = &pContext->FirstEnumPrinter; pInfo->pcEnumObjs = &pContext->cEnumPrinters; pInfo->DataMutex = CreateMutex( NULL, FALSE, NULL ); #ifdef SEP_WAITHANDLE
pInfo->phWaitObject = &pContext->hServerWait; pInfo->phMain = &pContext->hServer; #else
pInfo->phWaitObject = &pContext->hServer; #endif
pInfo->WaitFlags = PRINTER_CHANGE_PRINTER; pInfo->pfnRefresh = (REFRESHPROC)RefreshServerContext; pInfo->pfnCheckQuit = NULL; pInfo->pfnInitThread = (INITTHREADPROC)InitServerWindowThread; // pInfo->SuspendRefresh = FALSE;
pInfo->RefreshSignal = CreateEvent( NULL, EVENT_RESET_MANUAL, EVENT_INITIAL_STATE_SIGNALED, NULL ); pInfo->hicon = hiconServer;
if( pInfo->RefreshSignal == NULL ) DBGMSG( DBG_WARNING, ( "CreateEvent failed: Error %d\n", GetLastError( ) ) ); pInfo->pContext = pContext;
return pInfo; }
/* DisplayStatusIcon
* * This rather goes against the spirit of the data-driven model here, * in that we need to know about the various states that documents and printers * can be in. * * andrewbe - May 1992 */ BOOL DisplayStatusIcon( HDC hdc, PRECT prect, int WindowType, PBYTE pData, BOOL Highlight ) { BOOL DisplayIcon = TRUE; int BitmapIndex; DWORD Status; int xBase; int yBase; int right;
Status = *(DWORD *)pData;
switch( WindowType ) { case MDIWIN_LOCALPRINTER: case MDIWIN_NETWORKPRINTER: case MDIWIN_LOCALNETWORKPRINTER: if( ( Status & JOB_STATUS_ERROR ) ||( Status & JOB_STATUS_OFFLINE ) ||( Status & JOB_STATUS_PAPEROUT ) ) BitmapIndex = BM_IND_DOCUMENT_ERROR; else if( Status & JOB_STATUS_PAUSED ) BitmapIndex = BM_IND_DOCUMENT_PAUSED; else if( ( Status & JOB_STATUS_PRINTING ) ||( Status & JOB_STATUS_SPOOLING ) ) BitmapIndex = BM_IND_DOCUMENT_PRINTING; else DisplayIcon = FALSE;
xBase = BM_IND_STATUS_XBASE; yBase = BM_IND_STATUS_YBASE;
break;
case MDIWIN_SERVER: default: if( Status & PRINTER_STATUS_ERROR ) BitmapIndex = BM_IND_PRINTER_ERROR; else if( Status & PRINTER_STATUS_PAUSED ) BitmapIndex = BM_IND_PRINTER_PAUSED; else BitmapIndex = BM_IND_PRINTER_READY;
xBase = BM_IND_STATUS_XBASE; yBase = BM_IND_STATUS_YBASE;
break; }
/* Remember the old right coordinate of the drawing area:
*/ right = prect->right;
if( DisplayIcon ) { BitBlt( hdc, prect->left + STATUS_BITMAP_MARGIN, prect->top, STATUS_BITMAP_WIDTH, STATUS_BITMAP_HEIGHT, hdcMem, ( xBase + ( BitmapIndex * STATUS_BITMAP_WIDTH ) ), ( yBase + ( Highlight ? STATUS_BITMAP_HEIGHT : 0 ) ), SRCCOPY );
/* Draw around it so we don't get a flashing effect on the highlight line:
*/ prect->right = ( prect->left + STATUS_BITMAP_MARGIN ); DrawLine( hdc, prect, TEXT(""), Highlight );
prect->left += STATUS_BITMAP_MARGIN + STATUS_BITMAP_WIDTH; prect->right = prect->left + STATUS_BITMAP_MARGIN; DrawLine( hdc, prect, TEXT(""), Highlight );
prect->left += STATUS_BITMAP_MARGIN; }
else { prect->right = STATUS_BITMAP_SPACE; DrawLine( hdc, prect, TEXT(""), Highlight );
prect->left += STATUS_BITMAP_SPACE; }
/* Restore the right coordinate (left has now been updated to the new position):
*/ prect->right = right;
return DisplayIcon; }
/* FormatData
* * Takes a generic data pointer, along with the datatype to be formatted, * and generates a string. * * andrewbe wrote it - April 1992 */ VOID FormatData( PBYTE pData, int Datatype, LPTSTR string ) { TCHAR FormattedSize[MAX_PATH]; LARGE_INTEGER liTemp;
switch( Datatype ) { case MDIDATA_DWORD:
liTemp.LowPart = *(DWORD *)pData; liTemp.HighPart = 0;
FormatFileSize (THOUSANDSEPSWITCH, &liTemp, 0, FormattedSize); _stprintf( string, TEXT("%s"), FormattedSize ); break;
case MDIDATA_DWORD_BLANK_IF_ZERO: if( *(PCHAR *)pData != 0 ) {
liTemp.LowPart = *(DWORD *)pData; liTemp.HighPart = 0;
FormatFileSize (THOUSANDSEPSWITCH, &liTemp, 0, FormattedSize); _stprintf( string, TEXT("%s"), FormattedSize );
} else *string = NULLC; break;
case MDIDATA_PSZ: if( *(PCHAR *)pData && **(PCHAR *)pData ) _stprintf( string, TEXT("%s"), *(PCHAR *)pData ); else *string = NULLC; break;
case MDIDATA_PSZ_UNTITLED_IF_NULL: if( *(PCHAR *)pData && **(PCHAR *)pData ) _stprintf( string, TEXT("%s"), *(PCHAR *)pData ); else _stprintf( string, TEXT("%s"), strUntitled ); break;
case MDIDATA_TIME: ConvertSystemTimeToChar((SYSTEMTIME *)pData, string); break;
case MDIDATA_SIZE: liTemp.LowPart = *(DWORD *)pData; liTemp.HighPart = 0;
FormatFileSize (THOUSANDSEPSWITCH, &liTemp, 0, FormattedSize); _stprintf( string, szSizeFormat, FormattedSize ); break;
case MDIDATA_PRINTER_STATUS: GetPrinterStatusString( (DWORD)*(PDWORD *)pData, string ); break;
case MDIDATA_JOB_STATUS: GetJobStatusString( (DWORD)*(PDWORD *)pData, string ); } }
/* GetPrinterStatusString
* * Loads the resource string corresponding to the supplied status code. * * andrewbe wrote it - April 1992 */ #define MAXLEN 40
int GetPrinterStatusString( DWORD Status, LPTSTR string ) { int stringID;
if( Status & PRINTER_STATUS_ERROR ) stringID = IDS_ERROR; else if( Status & PRINTER_STATUS_PAPER_JAM ) stringID = IDS_PAPER_JAM; else if( Status & PRINTER_STATUS_PAPER_OUT ) stringID = IDS_PAPEROUT; else if( Status & PRINTER_STATUS_MANUAL_FEED ) stringID = IDS_MANUAL_FEED; else if( Status & PRINTER_STATUS_PAPER_PROBLEM ) stringID = IDS_PAPER_PROBLEM; else if( Status & PRINTER_STATUS_OFFLINE ) stringID = IDS_OFFLINE; else if( Status & PRINTER_STATUS_IO_ACTIVE ) stringID = IDS_IO_ACTIVE; else if( Status & PRINTER_STATUS_BUSY ) stringID = IDS_BUSY; else if( Status & PRINTER_STATUS_PRINTING ) stringID = IDS_PRINTING; else if( Status & PRINTER_STATUS_OUTPUT_BIN_FULL ) stringID = IDS_OUTPUT_BIN_FULL; else if( Status & PRINTER_STATUS_NOT_AVAILABLE ) stringID = IDS_NOT_AVAILABLE; else if( Status & PRINTER_STATUS_WAITING ) stringID = IDS_WAITING; else if( Status & PRINTER_STATUS_PROCESSING ) stringID = IDS_PROCESSING; else if( Status & PRINTER_STATUS_INITIALIZING ) stringID = IDS_INITIALIZING; else if( Status & PRINTER_STATUS_WARMING_UP ) stringID = IDS_WARMING_UP; else if( Status & PRINTER_STATUS_TONER_LOW ) stringID = IDS_TONER_LOW; else if( Status & PRINTER_STATUS_NO_TONER ) stringID = IDS_NO_TONER; else if( Status & PRINTER_STATUS_PAGE_PUNT ) stringID = IDS_PAGE_PUNT; else if( Status & PRINTER_STATUS_USER_INTERVENTION ) stringID = IDS_USER_INTERVENTION; else if( Status & PRINTER_STATUS_OUT_OF_MEMORY ) stringID = IDS_OUT_OF_MEMORY; else if( Status & PRINTER_STATUS_DOOR_OPEN ) stringID = IDS_DOOR_OPEN; // else
// if( Status & PRINTER_STATUS_SERVER_UNKNOWN )
// stringID = IDS_SERVER_UNKNOWN;
else if( Status & PRINTER_STATUS_PAUSED ) stringID = IDS_PAUSED; else if( Status & PRINTER_STATUS_PENDING_DELETION ) stringID = IDS_PENDING_DELETION;
else if( Status & PRINTER_STATUS_ACCESS_DENIED ) stringID = IDS_ACCESS_DENIED; else if( Status & PRINTER_STATUS_UNKNOWN ) stringID = IDS_STATUS_UNKNOWN; else if( Status & PRINTER_STATUS_LOADING ) stringID = IDS_STATUS_LOADING;
//
// End
//
else stringID = IDS_READY;
return LoadString( hInst, stringID, string, MAXLEN ); }
/* GetJobStatusString
* * Loads the resource string corresponding to the supplied status code. * * andrewbe wrote it - April 1992 */ int GetJobStatusString( DWORD Status, LPTSTR string ) { int stringID;
if( Status & JOB_STATUS_ERROR ) stringID = IDS_ERROR; else if( Status & JOB_STATUS_OFFLINE ) stringID = IDS_OFFLINE; else if( Status & JOB_STATUS_PAPEROUT ) stringID = IDS_PAPEROUT; else if( Status & JOB_STATUS_DELETING ) stringID = IDS_DELETING; else if( Status & JOB_STATUS_PAUSED ) stringID = IDS_PAUSED; else if( ( Status & JOB_STATUS_SPOOLING ) && ( Status & JOB_STATUS_PRINTING ) ) stringID = IDS_PRINTANDSPOOL; else if( Status & JOB_STATUS_SPOOLING ) stringID = IDS_SPOOLING; else if( Status & JOB_STATUS_PRINTING ) stringID = IDS_PRINTING; else if( Status & JOB_STATUS_PRINTED ) stringID = IDS_PRINTED; else stringID = IDS_NOSTATUS;
return LoadString( hInst, stringID, string, MAXLEN ); }
VOID SetWindowTypeIcon( PQUEUE pQueue, DWORD WindowType, DWORD Flags) { pQueue->pMDIWinInfo->WindowType = WindowType;
switch( WindowType ) { case MDIWIN_NETWORKPRINTER: case MDIWIN_LOCALNETWORKPRINTER: pQueue->pMDIWinInfo->hicon = hiconConnect; break;
case MDIWIN_LOCALPRINTER: default: pQueue->pMDIWinInfo->hicon = ( ( Flags & CREATE_PRINTER_SHARED ) ? hiconShared : hiconPrinter ); break; } }
/* --- Function: DrawLine() -------------------------------------------------
* * Description: * Only draws lines visible portion of Printer and Job status lines * in window. * * ---------------------------------------------------------------------- */ void DrawLine( HDC hDC, LPRECT pRect, LPTSTR pStr, BOOL bInvert ) { unsigned long PrevColour, PrevTextColour; SIZE TextSize; int x, y;
if (bInvert) { PrevColour = SetBkColor(hDC, SysColorHighlight ); PrevTextColour = SetTextColor(hDC, SysColorHighlightText ); } else { /* Hack around a USER bug that gives me the wrong colours:
*/ SetBkColor(hDC, SysColorWindow ); SetTextColor(hDC, SysColorWindowText ); }
GetTextExtentPoint(hDC, pStr, _tcslen(pStr), &TextSize);
x = pRect->left; y = ( pRect->top + ( ( pRect->bottom - pRect->top - TextSize.cy ) / 2 ) );
ExtTextOut(hDC, x, y, ETO_OPAQUE | ETO_CLIPPED, pRect, pStr, _tcslen(pStr), NULL);
if (bInvert) { SetBkColor(hDC, PrevColour); SetTextColor(hDC, PrevTextColour); } }
long FrameWndProc( HWND hWnd, UINT message, WPARAM wParam, LONG lParam ) { if( message == WM_Help ) { FrameHelp(hWnd, (UINT)lParam); return 0; }
switch(message) {
case WM_CREATE: return FrameCreate(hWnd, (LPCREATESTRUCT)lParam);
case WM_DELETE_PRINTER: return FrameCommandDeletePrinterHelper(hWnd, (HWND)lParam, FALSE);
case WM_INIT_PRINTER_WINDOWS: InitQueueChildWindows(hWnd); return 0;
case WM_INIT_SERVER_WINDOWS: InitServerChildWindows(hWnd); return 0;
case WM_INITMENU: return FrameInitMenu(hWnd);
case WM_MENUSELECT: return FrameMenuSelect( hWnd, wParam, lParam );
case WM_PAINT: return FramePaint(hWnd);
case WM_SIZE: FrameSize(hWnd, wParam, lParam); break;
case WM_CLOSE: FrameClose(hWnd); return DefFrameProc(hWnd, hwndClient, message, wParam, lParam);
case WM_COMMAND: switch(LOWORD(wParam)) { case IDM_CONNECTTOPRINTER: return FrameCommandConnectToPrinter(hWnd);
case IDM_INSTALLPRINTER: return FrameCommandCreatePrinter(hWnd);
case IDM_PROPERTIES: return FrameCommandProperties(hWnd);
case IDM_REMOVECONNECTION: /* Toolbar button only */ case IDM_DELETEPRINTER: return FrameCommandDeletePrinter(hWnd);
case IDM_PRINTER_PAUSE: return FrameCommandPrinterPauseResume(hWnd, TRUE);
case IDM_PRINTER_RESUME: return FrameCommandPrinterPauseResume(hWnd, FALSE);
case IDM_PURGEPRINTER: return FrameCommandPurgePrinter(hWnd);
case IDM_FORMS: return FrameCommandForms(hWnd);
case IDM_SERVERVIEWER: return FrameCommandServerViewer(hWnd);
case IDM_EXIT: SendMessage(hWnd, WM_CLOSE, 0, 0L); return 0;
case IDM_REMOVEDOC: return FrameCommandRemoveDoc(hWnd);
case IDM_DOCTAILS: return FrameCommandDocDetails(hWnd);
case IDM_DOCUMENT_PAUSE: return FrameCommandDocumentPauseResume(hWnd, IDM_DOCUMENT_PAUSE);
case IDM_DOCUMENT_RESUME: return FrameCommandDocumentPauseResume(hWnd, IDM_DOCUMENT_RESUME);
case IDM_RESTART: return FrameCommandRestart(hWnd); #ifdef LATER
case IDM_FONT: return FrameCommandFont(hWnd);
case IDM_REFRESHRATE: return FrameCommandRefreshRate(hWnd); #endif
case IDM_TOOLBAR: return FrameCommandToolbar(hWnd);
case IDM_STATUSBAR: return FrameCommandStatusbar(hWnd);
case IDM_SAVESETTINGS: return FrameCommandSaveSettings(hWnd);
case IDM_PERMISSIONS: return FrameCommandPermissions(hWnd);
case IDM_AUDITING: return FrameCommandAuditing(hWnd);
case IDM_OWNER: return FrameCommandOwner(hWnd);
case IDM_TILEHORZ: SendMessage(hwndClient, WM_MDITILE, MDITILE_HORIZONTAL, 0L); return 0;
case IDM_TILEVERT: SendMessage(hwndClient, WM_MDITILE, MDITILE_VERTICAL, 0L); return 0;
case IDM_CASCADE: SendMessage(hwndClient, WM_MDICASCADE, 0, 0L); return 0;
case IDM_ARRANGE: SendMessage(hwndClient, WM_MDIICONARRANGE, 0, 0L); return 0;
case IDM_REFRESH: FrameCommandRefresh(hWnd); return 0;
case IDM_CLOSE: return FrameCommandClose(hWnd);
case IDM_HELP_CONTENTS: ShowHelp(hWnd, HELP_INDEX, (DWORD)TEXT("")); break;
case IDM_HELP_SEARCH: ShowHelp(hWnd, HELP_PARTIALKEY, (DWORD)TEXT("")); break;
case IDM_HELP_HOWTOUSE: ShowHelp(hWnd, HELP_HELPONHELP, (DWORD)TEXT("")); break;
case IDM_ABOUT: return FrameCommandAbout(hWnd);
case IDM_RETURN: return FrameCommandReturn();
case IDTB_CB_PRINTERS: FrameCommandDefaultPrinter(hWnd, HIWORD(wParam)); break;
case ID_TOOLBAR: FrameCommandToolbarNotify(hWnd, wParam, lParam); break;
case IDC_TAB: FrameCommandTab(hWnd); break;
default: return FrameCommandDefault(hWnd, wParam, lParam); } break;
#ifdef LATER
case WM_QUERYENDSESSION: case WM_CLOSE: SendMessage(hWnd, WM_COMMAND, IDM_CLOSEALL, 0L); if (NULL != GetWindow(hwndClient, GW_CHILD)) return 0; #endif
case WM_NOTIFY: { LPTOOLTIPTEXT lpTT = (LPTOOLTIPTEXT) lParam;
if (lpTT->hdr.code == TTN_NEEDTEXT) { if (!LoadString (hInst, lpTT->hdr.idFrom, lpTT->szText, 80)) lpTT->szText[0] = TEXT('\0'); } } break;
case WM_SYSCOLORCHANGE: FrameSysColorChange( ); break;
case WM_WININICHANGE: FrameWinIniChange( hWnd, (LPTSTR)lParam ); break;
case WM_DROPOBJECT: return 0x544E5250L; // 'PRNT' tells fm to print
case WM_UPDATE_DEFAULT: UpdateDefaultList( ); return 0;
case WM_PRINTER_ADDED: FramePrinterAdded(hWnd, wParam); return 0;
case WM_REG_NOTIFY_CHANGE_KEY_VALUE: FrameRegNotifyChangeKeyValue( hWnd, (HKEY)wParam ); return 0;
case WM_THREAD_ERROR: FrameThreadError(hWnd, (PMDIWIN_INFO)lParam, wParam); return 0;
case WM_DESTROY : PostQuitMessage(0); return 0;
default: return DefFrameProc(hWnd, hwndClient, message, wParam, lParam); }
// Pass unprocessed msgs to DefFrameProc(not DefWindowProc)
return 0; }
/*
* ROUTINES CALLED BY FrameWndProc: */
/*
* */ LONG FrameCreate(HWND hWnd, LPCREATESTRUCT pCreateStruct) { CLIENTCREATESTRUCT clientcreate; HMENU hMenu; HDC hDC; RECT rc; BOOL NetworkAccess; DWORD ThreadId; DWORD i;
SetWindowLong(hWnd, GWL_USERDATA, (LONG)pCreateStruct->lpCreateParams);
hwndFrame = hWnd;
hDC = GetDC(hWnd); GetTextMetrics(hDC, &tm); cy = tm.tmExternalLeading + tm.tmHeight; cx = tm.tmAveCharWidth;
dyBorder = GetSystemMetrics(SM_CYBORDER); dyBorderx2 = dyBorder * 2; // dyStatus = tm.tmHeight + tm.tmExternalLeading + 7 * dyBorder;
dxStatPrtField = GetDeviceCaps(hDC, LOGPIXELSX) * 3; // 3 inches
dxStatProgField = GetDeviceCaps(hDC, LOGPIXELSX) * 3 / 2; // 1 1/2 inches
dxStatQueField = GetDeviceCaps(hDC, LOGPIXELSX) * 2; // 2 inches
ReleaseDC(hWnd, hDC);
// OpenPrinterForSpecifiedAccess( NULL, &hLocalServer,
// PRINTER_ACCESS_HIGHEST_PERMITTED,
// &LocalPermission );
GetMaximumServerAccess( NULL, &LocalPermission, &hLocalServer );
if( hLocalServer ) CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)LocalServerThread, hLocalServer, 0, &ThreadId );
ThreadMessageWritten = CreateEvent( NULL, EVENT_RESET_AUTOMATIC, EVENT_INITIAL_STATE_NOT_SIGNALED, NULL ); if( ThreadMessageWritten == NULL ) DBGMSG( DBG_WARNING, ( "CreateEvent failed: Error %d\n", GetLastError( ) ) );
ThreadMessageRead = CreateEvent( NULL, EVENT_RESET_AUTOMATIC, EVENT_INITIAL_STATE_SIGNALED, NULL ); if( ThreadMessageRead == NULL ) DBGMSG( DBG_WARNING, ( "CreateEvent failed: Error %d\n", GetLastError( ) ) );
#if DBG
if( WaitForSingleObject( ThreadMessageRead, 0 ) != WAIT_OBJECT_0 ) DBGMSG( DBG_WARNING, ( "Event was not signaled!\n" ) ); SetEvent( ThreadMessageRead ); #endif /* DBG */
// Set initial state of some menu items
hMenu = GetMenu(hwndFrame);
if (bStatusBar) CheckMenuItem(hMenu, IDM_STATUSBAR, MF_BYCOMMAND | MF_CHECKED);
if (bToolBar) CheckMenuItem(hMenu, IDM_TOOLBAR, MF_BYCOMMAND | MF_CHECKED);
if (bSaveSettings) CheckMenuItem(hMenu, IDM_SAVESETTINGS, MF_BYCOMMAND | MF_CHECKED);
/* Get the handles of the popup menus:
*/ for( i = 0; i < POPUP_COUNT; i++ ) pMenuHelpIDs[i*2+3] = (DWORD)GetSubMenu( hMenu, i );
// Load resource strings
LoadString(hInst, IDS_UNTITLED, strUntitled, sizeof(strUntitled) / sizeof(*strUntitled)); LoadString(hInst, IDS_BYTES, szSizeFormat, sizeof(szSizeFormat) / sizeof(*szSizeFormat));
// CountryCode - krishnag
if (bJapan) {
// if we're NT-J
hfontHelv = NULL; hfontHelvBold = NULL; } else {
// we're not NT-J
hfontHelv = CreateFont(GetHeightFromPointsString(sz8), 0, 0, 0, 400, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, szHelv); hfontHelvBold = CreateFont(GetHeightFromPointsString(sz8), 0, 0, 0, 700, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, szHelv); }
CreateMDIDefaultColumns( hWnd, MDIHEAD_JOB_COUNT, IDS_FIRST_HEADER_PRINTER, MDIPrinterDefaultColumn, MDIPrinterMinimumCharacterWidth ); CreateMDIDefaultColumns( hWnd, MDIHEAD_PRINTER_COUNT, IDS_FIRST_HEADER_SERVER, MDIServerDefaultColumn, MDIServerMinimumCharacterWidth );
hcursorArrow = LoadCursor( NULL, IDC_ARROW ); hcursorWait = LoadCursor( NULL, IDC_WAIT ); hcursorReorder = LoadCursor( hInst, MAKEINTRESOURCE( IDC_REORDER ) );
InitializeInternationalTimeConstants( );
// Setup clientcreate struct for MDI windows and menu
clientcreate.hWindowMenu = GetSubMenu(GetMenu(hWnd), POPUP_WINDOW); clientcreate.idFirstChild = IDM_FIRSTCHILD;
GetClientRect(hWnd, &rc);
NetworkAccess = UserHasNetworkAccess( );
NetworkInstalled = NetworkIsInstalled( );
if( !NetworkAccess ) RemoveNetworkMenuItems( hWnd );
// Make toolbar window
hwndToolbar = PMCreateToolbar( NetworkAccess );
if (!hwndToolbar) return -1L;
hwndClient = CreateWindow(TEXT("MDICLIENT"), NULL, WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL, -dyBorder, -dyBorder + ( bToolBar ? DYTOOLBAR : 0 ), rc.right, rc.bottom, hWnd, (HMENU)1, hInst, (LPTSTR)&clientcreate);
hwndStatus = CreateWindow(STATUSCLASSNAME, TEXT(""), WS_CHILD | WS_BORDER | ( bStatusBar ? WS_VISIBLE : 0 ), -100, -100, 10, 10, hWnd, (HMENU) ID_STATUSBAR, hInst, NULL);
SendMessage( hwndStatus, WM_SIZE, 0, 0L );
// SetStatusMode( STATUS_MODE_NORMAL, FALSE );
if (!hwndClient) return -1L;
DragAcceptFiles( hWnd, TRUE );
PostMessage( hWnd, WM_INIT_PRINTER_WINDOWS, 0, 0 );
if( NetworkAccess ) PostMessage( hWnd, WM_INIT_SERVER_WINDOWS, 0, 0 );
return 0; }
VOID CreateMDIDefaultColumns( HWND hwnd, DWORD cColumns, DWORD idFirstHeader, PCOLUMN pColumns, PINT pDefaultWidths ) { DWORD i; TCHAR string[40]; HDC hdc; int dx; SIZE TxtSize; SIZE DefSize; /* Test buffer to check extent of default character width of columns.
* Must contain at least as many characters as the largest value in * Server/PrinterMinimumCharacterWidth: */ TCHAR TestBuffer[] = TEXT("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
/* Load the heading strings:
*/ for( i = 0; i < cColumns; i++ ) { LoadString(hInst, idFirstHeader + i, string, sizeof string / sizeof *string);
if( !( pColumns[i].Text = AllocSplStr( string ) ) ) pColumns[i].Text = szNULL; }
// Create columnar heading text fields in window
hdc = GetDC(hwnd);
for (i = 0; i < cColumns; i++) { SelectObject(hdc, hfontHelv); GetTextExtentPoint (hdc, pColumns[i].Text, _tcslen(pColumns[i].Text), &TxtSize);
// Allow for space on either side of char string
dx = TxtSize.cx + 4 * cx;
if( pDefaultWidths[i] ) GetTextExtentPoint (hdc, TestBuffer, pDefaultWidths[i], &DefSize); else DefSize.cx = 0;
dx = max( dx, DefSize.cx );
pColumns[i].Width = dx;
}
ReleaseDC(hwnd, hdc); }
/*
* */ VOID GetSystemColors( VOID ) { SysColorHighlight = GetSysColor( COLOR_HIGHLIGHT ); SysColorHighlightText = GetSysColor( COLOR_HIGHLIGHTTEXT ); SysColorWindow = GetSysColor( COLOR_WINDOW ); SysColorWindowText = GetSysColor( COLOR_WINDOWTEXT ); SysColorBtnFace = GetSysColor( COLOR_BTNFACE ); SysColorBtnText = GetSysColor( COLOR_BTNTEXT ); SysColorBtnHighlight = GetSysColor( COLOR_BTNHIGHLIGHT ); SysColorBtnShadow = GetSysColor( COLOR_BTNSHADOW ); SysColorWindowFrame = GetSysColor( COLOR_WINDOWFRAME ); }
/* UserHasNetworkAccess
* * Looks in the registry to see whether the Value under "Network" is set to 1. * * Three scenarios handled: * * 1. Key found and value == 1: Access granted * * 2. Key not found because it isn't there: Access granted * * 3. Key not found because of some other error: Access denied * * * Return value: * * Boolean * */ BOOL UserHasNetworkAccess( VOID ) { DWORD AccessFlag; DWORD rc; BOOL AccessGranted;
REGISTRY_ENTRY RegistryNetworkEntry = { REG_DWORD, sizeof(DWORD) };
rc = ReadRegistryData( NULL, TEXT("Network"), (LPBYTE)&AccessFlag, &RegistryNetworkEntry );
switch( rc ) { case NO_ERROR: AccessGranted = ( AccessFlag == 1 ); break;
case ERROR_FILE_NOT_FOUND: AccessGranted = TRUE; break;
default: AccessGranted = FALSE; }
return AccessGranted; }
/* RemoveNetworkMenuItems
* * Removes the following menu items in the Printer pull-down: * * Connect to Printer... * Remove Printer Connection * Server Viewer... * ������������������������� (separator) * */ VOID RemoveNetworkMenuItems( HWND hwnd ) { HMENU hSubMenu;
/* Get the handle of the Printer pull-down menu:
*/ hSubMenu = GetSubMenu( GetMenu( hwnd ), 0 );
DeleteMenu( hSubMenu, 13, MF_BYPOSITION ); DeleteMenu( hSubMenu, IDM_SERVERVIEWER, MF_BYCOMMAND ); DeleteMenu( hSubMenu, IDM_CONNECTTOPRINTER, MF_BYCOMMAND ); // DeleteMenu( hSubMenu, IDM_REMOVECONNECTION, MF_BYCOMMAND );
}
/* NetworkIsInstalled
* * This routine checks to see whether there is a value in the registry * which will indicate that the network is installed. * * The alternative would be to call WNetOpenEnum, but this drags in * MPR and other stuff. */ BOOL NetworkIsInstalled( VOID ) { DWORD Status; HKEY hkeyNetworkProviderOrder; DWORD Size; BOOL rc = FALSE;
Status = RegOpenKeyEx( HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Control\\NetworkProvider\\Order"), 0, KEY_READ, &hkeyNetworkProviderOrder );
if( Status == NO_ERROR ) { Status = RegQueryValueEx( hkeyNetworkProviderOrder, TEXT("ProviderOrder"), 0, NULL, NULL, &Size );
if( Status == NO_ERROR ) rc = TRUE;
RegCloseKey( hkeyNetworkProviderOrder ); }
return rc; }
/* SetStatusMode
* */ VOID SetStatusMode( int Mode, BOOL Update ) { INT RightOfPane[SF_COUNT];
RightOfPane[0] = dxStatPrtField; RightOfPane[1] = dxStatPrtField + dxStatProgField; RightOfPane[2] = dxStatPrtField + dxStatProgField + dxStatQueField;
switch( Mode ) { case STATUS_MODE_NORMAL: SendMessage( hwndStatus, SB_SIMPLE, FALSE, 0 ); SendMessage( hwndStatus, SB_SETPARTS, SF_COUNT, (LPARAM)RightOfPane ); SendMessage( hwndStatus, WM_SIZE, 0, 0L ); break;
case STATUS_MODE_HELP: SendMessage( hwndStatus, SB_SIMPLE, TRUE, 0 ); SendMessage( hwndStatus, WM_SIZE, 0, 0L ); break; }
if( Update ) UpdateStatus( NULL ); }
//
// Used to display any error message from worker threads.
// (This ensures even synchronization of multiple error message
// boxes and prevents the worker thread from any calling user.)
//
// We also check dwError for bit 29 (CustomerBit), which the
// Sendee can use as an extra bit of info.
//
LONG FrameThreadError( HWND hWnd, PMDIWIN_INFO pMDIWinInfo, DWORD dwError) { LPTSTR pErrorString; BOOL bCustomerCode = FALSE;
if (pMDIWinInfo->Alive) { if (dwError & (1<<29)) { bCustomerCode = TRUE;
//
// Now turn the bit off so we can use it normally with
// FormatMessage();
//
dwError &= ~(1<<29); }
pErrorString = GetErrorString(dwError);
switch(pMDIWinInfo->WindowType) { case MDIWIN_SERVER:
//
// In InitServerWindowThread, we set bit 29 if the error
// indicates we couldn't open the server for auto refresh,
// but we could enumerate.
//
Message( hWnd, MSG_ERROR, IDS_PRINTMANAGER, #if 0
//
// Turned off in threads.c, so turn off
// here.
//
bCustomerCode ? IDS_COULDNOTOPENSERVERREFRESH : #endif
IDS_COULDNOTGETSERVERINFO, ((PSERVER_CONTEXT)pMDIWinInfo->pContext)->pServerName, pErrorString );
break;
default:
Message( hWnd, MSG_ERROR, IDS_PRINTMANAGER, IDS_OPEN_PRINTER_FAILED, ((PQUEUE)pMDIWinInfo->pContext)->pPrinterName, pErrorString ); break; }
FreeSplStr( pErrorString ); }
return 0; }
/*
* */ LONG FrameInitMenu(HWND hWnd) { HWND hwndChild; PMDIWIN_INFO pMDIWinInfo; PQUEUE pQueue = NULL; PSERVER_CONTEXT pServerContext = NULL; UINT State; HMENU hMenu; PPRINTER_INFO_2 pPrinter; BOOL PrinterExists; BOOL PrinterPaused; BOOL DocumentExists; BOOL DocumentSelected; BOOL DocumentPaused; BOOL PrinterIsLocal; // Undefined if !PrinterExists
BOOL UserHasServerAdminAccess = FALSE; BOOL UserHasPrinterAdminAccess = FALSE; BOOL ShowSecurity = FALSE; BOOL PermitAuditing = FALSE; BOOL ForceRefresh = TRUE;
// Disable (Grey) some menu items if there are no printers
// or if there are no jobs selected (or no jobs at all) on
// the active printer
hwndChild = (HWND) SendMessage(hwndClient, WM_MDIGETACTIVE, 0, 0L);
hMenu = GetMenu(hWnd);
if( hwndChild && (pMDIWinInfo = GETMDIWIN( hwndChild ))) { ENTER_PROTECTED_DATA( pMDIWinInfo );
if( pMDIWinInfo->WindowType == MDIWIN_SERVER ) { pServerContext = (PSERVER_CONTEXT)pMDIWinInfo->pContext; PrinterExists = ( pServerContext->cPrinters > 0 ); if( PrinterExists ) { PrinterIsLocal = TRUE; // because it's local to the server we're looking at
pPrinter = pServerContext->pSelPrinter; PrinterPaused = ( pPrinter->Status & PRINTER_STATUS_PAUSED ); }
/* Can't manipulate jobs from Server windows:
*/ DocumentExists = FALSE;
DocumentSelected = FALSE; DocumentPaused = FALSE;
/* Need to check for this:
*/ UserHasServerAdminAccess = ( pServerContext->AccessGranted & SERVER_ACCESS_ADMINISTER );
/* Check whether the Printer Pause button is enabled.
* If so, the user must have Administer access on the selected printer: */ UserHasPrinterAdminAccess = IS_BUTTON_ENABLED( IDM_PRINTER_PAUSE );
/* Don't show Security options for server windows:
*/ ForceRefresh = FALSE; } else { pQueue = (PQUEUE)pMDIWinInfo->pContext; pPrinter = pQueue->pPrinter;
PrinterExists = TRUE; PrinterIsLocal = ( ( pMDIWinInfo->WindowType == MDIWIN_LOCALPRINTER ) ||( pMDIWinInfo->WindowType == MDIWIN_LOCALNETWORKPRINTER ) );
if( pPrinter ) PrinterPaused = ( pPrinter->Status & PRINTER_STATUS_PAUSED ); else PrinterPaused = FALSE;
if( ( !pPrinter ) ||( pQueue->SelJobId == 0 ) ||( pPrinter->cJobs == 0 ) ) { if( !pPrinter || ( pPrinter->cJobs == 0 ) ) DocumentExists = FALSE; else DocumentExists = TRUE;
DocumentSelected = FALSE; DocumentPaused = FALSE; } else { DocumentExists = TRUE; DocumentSelected = TRUE; DocumentPaused = ( pQueue->pSelJob->Status & JOB_STATUS_PAUSED ); }
/* Administer privilege on the server is needed to create a printer:
*/ UserHasServerAdminAccess = ( LocalPermission & SERVER_ACCESS_ADMINISTER );
/* Administer privilege on the printer is needed to delete a printer:
*/ UserHasPrinterAdminAccess = ( pQueue->AccessGranted & PRINTER_ACCESS_ADMINISTER );
/* Always enable the Permissions and Take Ownership options.
* The user requires READ_CONTROL to see them, which he probably * has: */ ShowSecurity = TRUE;
/* Auditing actually requires ACCESS_SYSTEM_SECURITY privilege.
*/ PermitAuditing = TRUE; }
LEAVE_PROTECTED_DATA( pMDIWinInfo );
} else { PrinterExists = FALSE; PrinterPaused = FALSE; DocumentExists = FALSE; DocumentSelected = FALSE; DocumentPaused = FALSE;
UserHasServerAdminAccess = ( LocalPermission & SERVER_ACCESS_ADMINISTER ); }
State = MF_BYCOMMAND | ( PrinterExists ? MF_ENABLED : MF_GRAYED ); EnableMenuItem(hMenu, IDM_FORMS, State); State = MF_BYCOMMAND | ( ( ( PrinterExists && PrinterIsLocal && UserHasPrinterAdminAccess /* We need a handle to delete the printer. */ /* This may not be so if it's down: */ && ( pQueue ? (BOOL)pQueue->hPrinter : TRUE ) ) ||( PrinterExists && !PrinterIsLocal ) ) ? MF_ENABLED : MF_GRAYED ); EnableMenuItem(hMenu, IDM_DELETEPRINTER, State); // State = MF_BYCOMMAND | ( ( PrinterExists && !PrinterIsLocal ) ? MF_ENABLED : MF_GRAYED );
// EnableMenuItem(hMenu, IDM_REMOVECONNECTION, State);
State = MF_BYCOMMAND | ( ( PrinterExists && pPrinter ) ? MF_ENABLED : MF_GRAYED ); EnableMenuItem(hMenu, IDM_PROPERTIES, State);
if( UserHasPrinterAdminAccess ) { State = MF_BYCOMMAND | ( ( PrinterExists && !PrinterPaused ) ? MF_ENABLED : MF_GRAYED ); EnableMenuItem(hMenu, IDM_PRINTER_PAUSE, State); State = MF_BYCOMMAND | ( ( PrinterExists && PrinterPaused ) ? MF_ENABLED : MF_GRAYED ); EnableMenuItem(hMenu, IDM_PRINTER_RESUME, State); State = MF_BYCOMMAND | ( DocumentExists ? MF_ENABLED : MF_GRAYED ); EnableMenuItem(hMenu, IDM_PURGEPRINTER, State); } else { /* Grey out both Pause and Resume Printer menu items if no Admin priv:
*/ State = MF_BYCOMMAND | MF_GRAYED; EnableMenuItem(hMenu, IDM_PRINTER_PAUSE, State); EnableMenuItem(hMenu, IDM_PRINTER_RESUME, State); EnableMenuItem(hMenu, IDM_PURGEPRINTER, State); }
State = MF_BYCOMMAND | ( DocumentSelected ? MF_ENABLED : MF_GRAYED ); EnableMenuItem(hMenu, IDM_REMOVEDOC, State); EnableMenuItem(hMenu, IDM_DOCTAILS, State); EnableMenuItem(hMenu, IDM_RESTART, State);
/* We can't get enough information to determine whether the user had
* Administer Document privilege, so we'll just have to enable the * Pause or Resume Document menu item; */ State = MF_BYCOMMAND | ( ( DocumentSelected && !DocumentPaused ) ? MF_ENABLED : MF_GRAYED ); EnableMenuItem(hMenu, IDM_DOCUMENT_PAUSE, State); State = MF_BYCOMMAND | ( ( DocumentSelected && DocumentPaused ) ? MF_ENABLED : MF_GRAYED ); EnableMenuItem(hMenu, IDM_DOCUMENT_RESUME, State);
State = MF_BYCOMMAND | ( hwndChild ? MF_ENABLED : MF_GRAYED ); EnableMenuItem(hMenu, IDM_CASCADE, State); EnableMenuItem(hMenu, IDM_TILEHORZ, State); EnableMenuItem(hMenu, IDM_TILEVERT, State); EnableMenuItem(hMenu, IDM_ARRANGE, State); EnableMenuItem(hMenu, IDM_REFRESH, State);
State = MF_BYCOMMAND | ( UserHasServerAdminAccess ? MF_ENABLED : MF_GRAYED ); EnableMenuItem(hMenu, IDM_INSTALLPRINTER, State);
State = MF_BYCOMMAND | ( ShowSecurity ? MF_ENABLED : MF_GRAYED ); EnableMenuItem(hMenu, IDM_PERMISSIONS, State); EnableMenuItem(hMenu, IDM_OWNER, State);
State = MF_BYCOMMAND | ( PermitAuditing ? MF_ENABLED : MF_GRAYED ); EnableMenuItem(hMenu, IDM_AUDITING, State);
State = MF_BYCOMMAND | ( ForceRefresh ? MF_ENABLED : MF_GRAYED ); EnableMenuItem(hMenu, IDM_REFRESH, State);
State = MF_BYCOMMAND | ( NetworkInstalled ? MF_ENABLED : MF_GRAYED ); EnableMenuItem(hMenu, IDM_CONNECTTOPRINTER, State); EnableMenuItem(hMenu, IDM_SERVERVIEWER, State);
return 0; }
/*
* */ LONG FrameMenuSelect( HWND hwnd, WPARAM wParam, LPARAM lParam ) { UINT ItemID; UINT Flags; HMENU hmenu;
ItemID = (UINT)LOWORD( wParam ); Flags = (UINT)HIWORD( wParam ); hmenu = (HMENU)lParam;
/* HACK:
* * If the item is in the "Windows" popup, but isn't between "Cascade" * and "Refresh" it must be the name of an MDI window added by the system. * We don't know the IDs of these added menu items - can we find out? */ if( ( (DWORD)hmenu == pMenuHelpIDs[POPUP_WINDOW*2+3] ) &&( ( ItemID < IDM_CASCADE ) || ( ItemID > IDM_REFRESH ) ) ) { ItemID = IDS_HELP_MDIWINDOW; WinHelpMenuID = ID_HELP_MDIWINDOW; }
/* Another hack:
* * If the item selected is IDM_DELETEPRINTER and the active window * is a network printer, change it to the now obsolete IDM_REMOVECONNECTION, * since this has more appropriate help information: */ if( ItemID == IDM_DELETEPRINTER ) { HWND hwndChild; PMDIWIN_INFO pMDIWinInfo;
if( hwndChild = (HWND) SendMessage(hwndClient, WM_MDIGETACTIVE, 0, 0L) ) { pMDIWinInfo = GETMDIWIN( hwndChild );
if( ( pMDIWinInfo->WindowType == MDIWIN_NETWORKPRINTER ) ||( pMDIWinInfo->WindowType == MDIWIN_LOCALNETWORKPRINTER ) ) ItemID = IDM_REMOVECONNECTION; } }
MenuHelp( WM_MENUSELECT, MAKEWPARAM( ItemID, HIWORD( wParam ) ), lParam, GetMenu( hwnd ), hInst, hwndStatus, pMenuHelpIDs);
if( ItemID && ( Flags & MF_SYSMENU ) ) WinHelpMenuID = ID_HELP_FRAME_SYSMENU; else WinHelpMenuID = ItemID;
return 0; }
/*
* */ LONG FramePaint(HWND hWnd) { PAINTSTRUCT ps;
BeginPaint(hWnd, &ps); EndPaint(hWnd, &ps);
return 0; }
/*
* */ VOID FrameSize(HWND hWnd, WPARAM Type, long Dimensions) { RECT rc; int dx, dy; int yToolbar, dyTB, yClientTop; int ToolbarHeight;
if (Type != SIZEICONIC) {
// make things look good by putting WS_BORDER on the
// client, then adjust the thing so it gets clipped
dx = LOWORD(Dimensions) + dyBorderx2; dy = HIWORD(Dimensions) + dyBorderx2;
if (bStatusBar) { GetWindowRect( hwndStatus, &rc ); dy -= ( rc.bottom - rc.top - 1); }
GetWindowRect( hwndToolbar, &rc ); ToolbarHeight = ( rc.bottom - rc.top );
if (bToolBar) { dy -= ToolbarHeight + 1; yToolbar = -dyBorder; dyTB = ToolbarHeight + dyBorder; yClientTop = ToolbarHeight - dyBorder; } else { dy += 1; yToolbar = -2 * ToolbarHeight; dyTB = ToolbarHeight; yClientTop = -dyBorder; }
// Size the MDI CLIENT window
MoveWindow(hwndClient, -dyBorder, yClientTop, dx, dy, TRUE);
// Size the TOOLBAR window
MoveWindow(hwndToolbar, -dyBorder, yToolbar, dx, dyTB, TRUE);
// if (bStatusBar)
// {
// GetClientRect(hwndFrame, &rc);
// rc.top = rc.bottom - dyStatus;
// InvalidateRect(hWnd, &rc, TRUE);
// }
SendMessage( hwndStatus, WM_SIZE, 0, 0L );
/* Bug #14592
* Make sure the combo-box doesn't get detached: */ SendMessage( hwndPrinterList, CB_SHOWDROPDOWN, (WPARAM)FALSE, 0 ); } }
/*
* */ VOID FrameClose(HWND hwnd) { int i; HWND hwndMDI; DWORD Options; REGISTRY_ENTRY RegistrySaveSettings = { REG_DWORD, sizeof(DWORD) }; TCHAR SaveSettings[40];
Options = 0; if( !bToolBar ) Options |= OPTION_NOTOOLBAR; if( !bStatusBar ) Options |= OPTION_NOSTATUSBAR; if( !bSaveSettings ) Options |= OPTION_NOSAVESETTINGS;
if( bSaveSettings ) { /* First delete the sections in the INI file, so we don't need to worry
* if queues have been deleted or printer names have been changed * (since we use the printer name as the INI key name): */ DeleteRegistryValues( szRegPrinters ); DeleteRegistryValues( szRegServers );
SaveWindowPos( hwnd, Options, FALSE );
for( hwndMDI = GetWindow( hwndClient, GW_CHILD ); hwndMDI; hwndMDI = GetWindow( hwndMDI, GW_HWNDNEXT ) ) { SaveWindowPos( hwndMDI, 0, TRUE ); } }
LoadString(hInst, IDS_SAVE_SETTINGS, SaveSettings, sizeof SaveSettings / sizeof *SaveSettings);
WriteRegistryData( NULL, SaveSettings, (LPBYTE)&bSaveSettings, &RegistrySaveSettings );
ClosePrinter( hLocalServer );
/* Ensure that any help instances go away.
* This does nothing if help hasn't been invoked: */ ShowHelp(hwnd, HELP_QUIT, 0); }
/*
* */ VOID FrameHelp(HWND hwnd, UINT HelpID) { if( HelpID != 0 ) ShowHelp(hwnd, HELP_CONTEXT, HelpID); else ShowHelp(hwnd, HELP_INDEX, (DWORD)TEXT("")); }
/* SaveWindowPos
* * Saves Print Manager window positions in the registry. * MDIWindow is FALSE for the main window. * */ VOID SaveWindowPos( HWND hwnd, DWORD Options, BOOL MDIWindow ) { PMDIWIN_INFO pMDIWinInfo = NULL; LPTSTR pWindowName; TCHAR WindowName[40]; LPTSTR pWindowType; DWORD cbRegistryData; DWORD cHeaders; PREGISTRY_DATA pRegistryData; INT i;
/* Get the size of the fixed part of the registry data:
*/ cbRegistryData = ( sizeof( REGISTRY_DATA ) - sizeof( pRegistryData->Headers ) );
/* Check there's some text.
* (We can't rely on return from GETMDIWIN, because there are some * children of the MDI client that aren't MDI windows, * and this causes a (non-fatal) exception because of the * invalid index for that window.) */ GetWindowText( hwnd, WindowName, sizeof WindowName/sizeof(TCHAR) );
if( !*WindowName ) return;
if( !MDIWindow ) { pWindowName = GetString( IDS_PRINTMANAGER ); pWindowType = NULL; cHeaders = 0; } else { /* Don't use the actual window text for MDI windows,
* since a paused printer has the additional string " - Paused" * in the title. */ pMDIWinInfo = GETMDIWIN( hwnd );
switch( pMDIWinInfo->WindowType ) { case MDIWIN_SERVER: default: pWindowType = szRegServers; pWindowName = ( (PSERVER_CONTEXT)pMDIWinInfo->pContext )->pServerName; cHeaders = pMDIWinInfo->cColumns; break;
case MDIWIN_LOCALPRINTER: case MDIWIN_NETWORKPRINTER: case MDIWIN_LOCALNETWORKPRINTER: pWindowType = szRegPrinters; pWindowName = ( (PQUEUE)pMDIWinInfo->pContext )->pPrinterName; cHeaders = pMDIWinInfo->cColumns; break; } }
cbRegistryData += ( cHeaders * sizeof pRegistryData->Headers );
pRegistryData = AllocSplMem( cbRegistryData );
if( !pRegistryData ) return;
/* Make sure there's a window title for the key name:
*/ if( *pWindowName ) { pRegistryData->WindowPlacement.length = sizeof(pRegistryData->WindowPlacement);
if( GetWindowPlacement( hwnd, &pRegistryData->WindowPlacement ) ) { pRegistryData->Options = Options; RegistryEntries.Size = cbRegistryData;
if( MDIWindow ) { for( i = 0; i < pMDIWinInfo->cColumns; i++ ) pRegistryData->Headers[i] = pMDIWinInfo->pColumns[i].Width; }
WriteRegistryData( pWindowType, pWindowName, (LPBYTE)pRegistryData, &RegistryEntries ); } }
FreeSplMem( pRegistryData );
if( !MDIWindow ) FreeSplStr( pWindowName ); }
/*
* */ LONG FrameCommandConnectToPrinter(HWND hWnd) { HANDLE hPrinter; LPPRINTER_INFO_2 pPrinter = NULL; DWORD cbPrinter = 0; PQUEUE pQueue; HWND hwndActive; PMDIWIN_INFO pInfo = NULL; HWND hwndPrinter; LPWSTR pszPrinterName;
SetCursor( hcursorWait );
hPrinter = ConnectToPrinterDlg( hWnd, 0 );
if( hPrinter ) { if( GetGeneric( (PROC)GetPrinter, 2, (PBYTE *)&pPrinter, cbPrinter, &cbPrinter, (PVOID)hPrinter, NULL ) ) { //
// If it's local and not remote, yet it begins with \\,
// remove the server name since the server is the local
// machine, and the printer window won't have the server name.
//
// This handles the case when we attempt to connect to
// a local printer.
//
if ((pPrinter->Attributes & PRINTER_ATTRIBUTE_LOCAL) && !(pPrinter->Attributes & PRINTER_ATTRIBUTE_NETWORK) && pPrinter->pPrinterName[0] == BACKSLASH && pPrinter->pPrinterName[1] == BACKSLASH) { pszPrinterName = _tcsrchr(&pPrinter->pPrinterName[2], BACKSLASH); pszPrinterName++; } else { pszPrinterName = pPrinter->pPrinterName; }
hwndPrinter = FindPrinterWindow( pszPrinterName );
/* Don't create a new window if we already have a connexion
* to this printer: */ if( hwndPrinter ) { SendMessage( hwndClient, WM_MDIACTIVATE, (WPARAM)hwndPrinter, 0L );
if( IsIconic( hwndPrinter ) ) ShowWindow( hwndPrinter, SW_RESTORE ); }
else { pQueue = AllocQueue( pPrinter->pPrinterName );
if( pQueue ) { pQueue->Error = OpenThreadObject(pQueue->pPrinterName, &pQueue->hPrinter, &pQueue->AccessGranted, MDIWIN_NETWORKPRINTER); if( !pQueue->Error ) { DWORD WindowType; DWORD Flags = 0;
pQueue->pServerName = AllocSplStr( pPrinter->pServerName );
if( ALL_FLAGS_ARE_SET( pPrinter->Attributes, PRINTER_ATTRIBUTE_NETWORK | PRINTER_ATTRIBUTE_LOCAL ) ) WindowType = MDIWIN_LOCALNETWORKPRINTER; else WindowType = MDIWIN_NETWORKPRINTER;
if( pPrinter->Attributes & PRINTER_ATTRIBUTE_SHARED ) Flags |= CREATE_PRINTER_SHARED;
CreateQueueWindow( hwndClient, pQueue, pPrinter->Status, WindowType, Flags ); } } }
FreeSplMem( pPrinter ); }
ClosePrinter( hPrinter );
hwndActive = (HWND)SendMessage(hwndClient, WM_MDIGETACTIVE, 0, 0L);
if( hwndActive ) pInfo = GETMDIWIN( hwndActive );
if( pInfo ) { ENTER_PROTECTED_DATA( pInfo );
UpdateDefaultList(); UpdateStatus( (HWND)TRUE );
LEAVE_PROTECTED_DATA( pInfo ); }
if( hwndActive ) EnableCheckTBButtons(hwndActive);
}
SetCursor( hcursorArrow );
return 0; }
/*
* */ LONG FrameCommandCreatePrinter(HWND hWnd) { PQUEUE pNewQueue; HWND hwndChild; PMDIWIN_INFO pMDIWinInfo; PRT_PROP_DLG_DATA PrtPropDlgData; LPPRINTER_INFO_2 pPrinter = NULL; DWORD cbPrinter = 0; BOOL Error = FALSE; BOOL Remote = FALSE;
/* Create a new window for this Print Queue and get Printer
* Properties. */
if (!(pNewQueue = AllocQueue(TEXT("")))) return 0;
hwndChild = (HWND) SendMessage (hwndClient, WM_MDIGETACTIVE, 0, 0L);
/* If the active window is iconic, don't worry whether it's a Server Viewer,
* we'll assume that the user wants to create the printer locally: */ if( hwndChild && !IsIconic( hwndChild ) ) pMDIWinInfo = GETMDIWIN( hwndChild ); else pMDIWinInfo = NULL;
ZERO_OUT( &PrtPropDlgData );
/* If this is a Server Viewer, set up the server name field.
* (Otherwise it's NULL.) */ if( pMDIWinInfo && ( pMDIWinInfo->WindowType == MDIWIN_SERVER ) ) { PSERVER_CONTEXT pServerContext = (PSERVER_CONTEXT)pMDIWinInfo->pContext;
Remote = TRUE;
if( pServerContext->pServerName ) PrtPropDlgData.pServerName = AllocSplStr( pServerContext->pServerName ); } else { PrtPropDlgData.pServerName = NULL; }
SetCursor( hcursorWait );
if( EnumGeneric( (PROC)EnumPrintProcessors, 1, (PBYTE *)&PrtPropDlgData.pPrintProcessors, 0, &PrtPropDlgData.cbPrintProcessors, &PrtPropDlgData.cPrintProcessors, PrtPropDlgData.pServerName, NULL, /* pEnvironment */ NULL ) ) /* (ignored) */ { if( DialogBoxParam( hInst, MAKEINTRESOURCE( DLG_PRTPROP ), hWnd, (DLGPROC)PrtPropDlg, (DWORD)&PrtPropDlgData ) == IDOK ) { if( !Remote ) { DWORD Flags = 0;
SetCursor( hcursorWait );
pNewQueue->pServerName = AllocSplStr(PrtPropDlgData.pServerName); pNewQueue->pPrinterName = PrtPropDlgData.pPrinterName; pNewQueue->hPrinter = PrtPropDlgData.hPrinter;
/* Save ourselves the bother of opening the printer again.
* We must have Admin privilege if we just created it: */ pNewQueue->AccessGranted |= PRINTER_ACCESS_ADMINISTER;
if( PrtPropDlgData.PrinterShared ) Flags |= CREATE_PRINTER_SHARED;
/* From here on, hwndChild is the new window:
*/ if( !( hwndChild = CreateQueueWindow( hWnd, pNewQueue, 0, MDIWIN_LOCALPRINTER, Flags ) ) ) Error = TRUE; else { PrinterAdded = TRUE;
if( GetGeneric( (PROC)GetPrinter, 2, (PBYTE *)&pPrinter, cbPrinter, &cbPrinter, (PVOID)pNewQueue->hPrinter, NULL ) ) { /* Change the icon for shared printers:
*/ if( pPrinter->Attributes & PRINTER_ATTRIBUTE_SHARED ) { pMDIWinInfo = GETMDIWIN( hwndChild ); pMDIWinInfo->hicon = hiconShared; }
FreeSplMem( pPrinter ); } } } else FreeQueue( pNewQueue ); } else Error = TRUE;
FreeSplMem( PrtPropDlgData.pPrintProcessors ); } else { Message( hWnd, MSG_ERROR, IDS_PRINTMANAGER, IDS_NO_PRINT_PROCESSORS ); Error = TRUE; }
if( Error ) { FreeQueue (pNewQueue); return 0; }
if( PrtPropDlgData.pServerName ) FreeSplStr( PrtPropDlgData.pServerName );
if( !Remote ) { PrinterProperties(hWnd, pNewQueue->hPrinter); }
UpdateDefaultList();
SetCursor( hcursorArrow );
return 0; }
/*
* */ LONG FrameCommandProperties(HWND hWnd) { HWND hwndChild; PMDIWIN_INFO pMDIWinInfo; PRT_PROP_DLG_DATA PrtPropDlgData; PQUEUE pQueue; PSERVER_CONTEXT pServerContext; BOOL OK = FALSE; DWORD OldAttributes;
hwndChild = (HWND) SendMessage (hwndClient, WM_MDIGETACTIVE, 0, 0L);
if (!hwndChild) return 0;
pMDIWinInfo = GETMDIWIN( hwndChild );
ENTER_PROTECTED_DATA( pMDIWinInfo );
ZERO_OUT( &PrtPropDlgData );
SetCursor( hcursorWait );
EnumGeneric( (PROC)EnumPrintProcessors, 1, (PBYTE *)&PrtPropDlgData.pPrintProcessors, 0, &PrtPropDlgData.cbPrintProcessors, &PrtPropDlgData.cPrintProcessors, PrtPropDlgData.pServerName, NULL, /* pEnvironment */ NULL ); /* (ignored) */
if( pMDIWinInfo->WindowType != MDIWIN_SERVER ) { pQueue = (PQUEUE)pMDIWinInfo->pContext;
/* Take a copy of the printer info, so that the dialog can scrawl
* over it without causing any problems. * (This doesn't copy the strings and other buffers, only the pointers.) */ if( !( PrtPropDlgData.pPrinter = AllocSplMem( sizeof( PRINTER_INFO_2 ) ) ) ) return 0; memcpy( PrtPropDlgData.pPrinter, pQueue->pPrinter, sizeof( PRINTER_INFO_2 ) );
PrtPropDlgData.pServerName = pQueue->pServerName; PrtPropDlgData.pMDIWinInfo = pQueue->pMDIWinInfo; PrtPropDlgData.hPrinter = pQueue->hPrinter; PrtPropDlgData.AccessGranted = pQueue->AccessGranted; PrtPropDlgData.ServerAccessGranted = LocalPermission;
OldAttributes = PrtPropDlgData.pPrinter->Attributes;
OK = DialogBoxParam( hInst, MAKEINTRESOURCE(DLG_PRTPROP), hWnd, (DLGPROC)PrtPropDlg, (DWORD)&PrtPropDlgData );
if( PrtPropDlgData.DriverChanged ) PrinterProperties(hWnd, pQueue->hPrinter);
/* If this is a local printer, and the shared attribute has changed,
* change the window's icon: */ if( OK &&( pMDIWinInfo->WindowType == MDIWIN_LOCALPRINTER ) &&( (BOOL)( OldAttributes & PRINTER_ATTRIBUTE_SHARED ) !=( PrtPropDlgData.PrinterShared ) ) ) { if( PrtPropDlgData.PrinterShared ) pMDIWinInfo->hicon = hiconShared; else pMDIWinInfo->hicon = hiconPrinter;
/* If the printer's MDI window is in iconic state,
* ensure that it gets repainted with the new icon: */ if( IsIconic( hwndChild ) ) InvalidateRect( hwndChild, NULL, TRUE ); } } else { pServerContext = (PSERVER_CONTEXT)pMDIWinInfo->pContext;
if( ( pServerContext->pSelPrinter ) &&( OpenPrinterForSpecifiedAccess( pServerContext->pSelPrinter->pPrinterName, &PrtPropDlgData.hPrinter, PRINTER_ACCESS_HIGHEST_PERMITTED, &PrtPropDlgData.AccessGranted ) ) ) { PrtPropDlgData.pServerName = pServerContext->pServerName;
if( !( PrtPropDlgData.pPrinter = AllocSplMem( sizeof( PRINTER_INFO_2 ) ) ) ) return 0; memcpy( PrtPropDlgData.pPrinter, pServerContext->pSelPrinter, sizeof( PRINTER_INFO_2 ) );
PrtPropDlgData.pMDIWinInfo = pServerContext->pMDIWinInfo; PrtPropDlgData.ServerAccessGranted = pServerContext->AccessGranted;
OK = DialogBoxParam( hInst, MAKEINTRESOURCE(DLG_PRTPROP), hWnd, (DLGPROC)PrtPropDlg, (DWORD)&PrtPropDlgData );
if( OK ) { if( PrtPropDlgData.DriverChanged ) { PrinterProperties(hWnd, PrtPropDlgData.hPrinter); } }
ClosePrinter( PrtPropDlgData.hPrinter ); }
else { ReportFailure( hWnd, 0, IDS_COULDNOTOPENPRINTER ); } }
if( OK ) FreeSplStr( PrtPropDlgData.pPrinterName );
FreeSplMem( PrtPropDlgData.pPrinter );
if (PrtPropDlgData.pPrintProcessors) FreeSplMem( PrtPropDlgData.pPrintProcessors );
LEAVE_PROTECTED_DATA( pMDIWinInfo );
return 0; }
/*
* */ LONG FrameCommandDeletePrinter( HWND hWnd) { HWND hwndMDIActive;
DBG_UNREFERENCED_PARAMETER(hWnd);
hwndMDIActive = (HWND)SendMessage(hwndClient, WM_MDIGETACTIVE, 0, 0L);
if (!hwndMDIActive) return 0;
return FrameCommandDeletePrinterHelper(hWnd, hwndMDIActive, TRUE); }
LONG FrameCommandDeletePrinterHelper( HWND hWnd, HWND hwndMDI, BOOL bConfirm) { BOOL OK = FALSE; PVOID pContext; PMDIWIN_INFO pMDIWinInfo = GETMDIWIN( hwndMDI );
if (!pMDIWinInfo) return 0;
if (pMDIWinInfo->Status & PRINTER_STATUS_LOADING) {
Message( hWnd, MSG_INFORMATION, IDS_PRINTMANAGER, IDS_PRINTER_NOT_LOADED); return 0; }
ENTER_PROTECTED_DATA( pMDIWinInfo );
pContext = pMDIWinInfo->pContext;
switch( pMDIWinInfo->WindowType ) { case MDIWIN_LOCALPRINTER: OK = DeleteLocalPrinter(hWnd, hwndMDI, (PQUEUE)pContext, bConfirm); break;
case MDIWIN_SERVER: OK = DeleteRemotePrinter(hWnd, (PSERVER_CONTEXT)pContext, bConfirm); break;
case MDIWIN_NETWORKPRINTER: case MDIWIN_LOCALNETWORKPRINTER: OK = DeleteConnection(hWnd, hwndMDI, (PQUEUE)pContext, bConfirm); break; }
LEAVE_PROTECTED_DATA( pMDIWinInfo );
if( OK ) { UpdateDefaultList();
/* If this was the last printer, we need to update the toolbar buttons:
*/ if(!SendMessage(hwndClient, WM_MDIGETACTIVE, 0, 0L)) { EnableCheckTBButtons(NULL); UpdateStatus(NULL); }
else { hwndMDI = (HWND)SendMessage(hwndClient, WM_MDIGETACTIVE, 0, 0L); pMDIWinInfo = GETMDIWIN( hwndMDI );
ENTER_PROTECTED_DATA( pMDIWinInfo ); UpdateStatus(hwndMDI); LEAVE_PROTECTED_DATA( pMDIWinInfo ); } } else { ReportFailure( hWnd, IDS_INSUFFPRIV_DELETEPRINTER, IDS_COULDNOTDELETEPRINTER ); }
return 0; }
/*
* */ BOOL DeleteLocalPrinter(HWND hwnd, HWND hwndMDI, PQUEUE pQueue, BOOL bConfirm) { LPTSTR pPrinterName; HANDLE hPrinter; BOOL OK = TRUE;
pPrinterName = pQueue->pPrinterName; hPrinter = pQueue->hPrinter;
/* Put up fairly innocuous confirmation message:
*/ if( !bConfirm || (Message( hwnd, MSG_YESNO, IDS_PRINTMANAGER, IDS_CONFIRMDELETE, pPrinterName ) == IDYES) ) { OK = DeletePrinter (hPrinter);
if( OK ) { DBG_IN_PROTECTED_DATA( pQueue->pMDIWinInfo );
KillMDIWinInfo(pQueue->pMDIWinInfo);
if (SendMessage(hwndMDI, WM_QUERYENDSESSION, 0, 0L)) SendMessage(hwndClient, WM_MDIDESTROY, (WPARAM)hwndMDI, 0L);
DBGMSG( DBG_TRACE, ( "Window destroyed\n" ) );
} }
return OK; }
/*
* */ BOOL DeleteRemotePrinter( HWND hwnd, PSERVER_CONTEXT pServerContext, BOOL bConfirm) { LPTSTR pPrinterName; LPTSTR pServerName; HANDLE hPrinter; HWND hwndPrinter = NULL; BOOL OK = TRUE;
pServerName = pServerContext->pServerName; pPrinterName = pServerContext->pSelPrinter->pPrinterName;
/* Get a handle to the printer:
*/ if( OpenPrinterForSpecifiedAccess( pPrinterName, &hPrinter, PRINTER_ALL_ACCESS, NULL ) ) { /* Put up scary message up to make sure they're sure they're sure:
*/ if( !bConfirm || (Message( hwnd, MSG_YESNO | MB_DEFBUTTON2, IDS_PRINTMANAGER, IDS_CONFIRMDELETEREMOTE, pServerName, pPrinterName ) == IDYES) ) { /* Do it:
*/ if( OK = DeletePrinter (hPrinter)) { PMDIWIN_INFO pMDIWinInfo = GETMDIWIN( hwndPrinter );
/* Now see if we have any connections to this printer:
*/ hwndPrinter = FindPrinterWindow( pPrinterName );
if( hwndPrinter ) { if( pMDIWinInfo ) { DBG_IN_PROTECTED_DATA( pMDIWinInfo ); KillMDIWinInfo(pMDIWinInfo); } else { DBGMSG( DBG_WARNING, ( "No MDIWinInfo in DeleteRemotePrinter\n" ) ); }
/* Blow away the MDI window:
*/ if (SendMessage(hwndPrinter, WM_QUERYENDSESSION, 0, 0L)) SendMessage(hwndClient, WM_MDIDESTROY, (WPARAM)hwndPrinter, 0L);
/* Get rid of the connection:
*/ DeletePrinterConnection( pPrinterName ); } } }
//
// Close it!
//
ClosePrinter(hPrinter); }
return OK; }
/*
* */ BOOL DeleteConnection(HWND hWnd, HWND hwndMDI, PQUEUE pQueue, BOOL bConfirm) { LPTSTR pPrinterName; BOOL OK;
DBG_UNREFERENCED_PARAMETER(hWnd);
pPrinterName = pQueue->pPrinterName;
/* Put up fairly innocuous confirmation message:
*/ if( !bConfirm || (Message( hWnd, MSG_YESNO, IDS_PRINTMANAGER, IDS_CONFIRMDELETECONNECTION, pPrinterName ) == IDYES) ) { /* This is a special case of a local printer masquerading
* as a network printer. */ if( pQueue->pMDIWinInfo->WindowType == MDIWIN_LOCALNETWORKPRINTER ) {
OK = DeletePrinter( pQueue->hPrinter ); if (OK) { if (pQueue->pPrinter && pQueue->pPrinter->pPortName) { //
// ignore errors from below
//
(void)WNetCancelConnection(pQueue->pPrinter->pPortName, TRUE) ; (void)RemoveFromReconnectList(pQueue->pPrinter->pPortName) ; } } } else OK = DeletePrinterConnection( pPrinterName );
if( OK ) { DBG_IN_PROTECTED_DATA( pQueue->pMDIWinInfo ); KillMDIWinInfo(pQueue->pMDIWinInfo);
if (SendMessage(hwndMDI, WM_QUERYENDSESSION, 0, 0L)) SendMessage(hwndClient, WM_MDIDESTROY, (WPARAM)hwndMDI, 0L);
return TRUE; }
else return FALSE; } }
/* FindPrinterWindow
* * Cycles through the MDI child windows until it finds a printer window * whose name matches that supplied. * * andrewbe - April 1992 */ HWND FindPrinterWindow( LPTSTR pPrinterName ) { HWND hwndMDI; BOOL Found; PMDIWIN_INFO pMDIWinInfo;
for( hwndMDI = GetWindow( hwndClient, GW_CHILD ), Found = FALSE; hwndMDI && !Found; hwndMDI = Found ? hwndMDI : GetWindow( hwndMDI, GW_HWNDNEXT ) ) { pMDIWinInfo = GETMDIWIN( hwndMDI );
if( pMDIWinInfo && ( pMDIWinInfo->WindowType != MDIWIN_SERVER ) ) if( !_tcscmp( ( (PQUEUE)pMDIWinInfo->pContext )->pPrinterName, pPrinterName ) ) Found = TRUE; }
return (Found ? hwndMDI : NULL); }
/*
* */ LONG FrameCommandPrinterPauseResume( HWND hWnd, BOOL bPause) { HWND hwndChild; PMDIWIN_INFO pMDIWinInfo; PQUEUE pQueue; PSERVER_CONTEXT pServerContext; PPRINTER_INFO_2 pPrinter = NULL; HANDLE hPrinter = NULL; BOOL ErrorOccurred = FALSE;
DBG_UNREFERENCED_PARAMETER(hWnd);
hwndChild = (HWND) SendMessage(hwndClient, WM_MDIGETACTIVE, 0, 0L);
if (!hwndChild) return 0;
pMDIWinInfo = GETMDIWIN( hwndChild );
ENTER_PROTECTED_DATA( pMDIWinInfo );
if( pMDIWinInfo->WindowType != MDIWIN_SERVER ) { pQueue = (PQUEUE)pMDIWinInfo->pContext; hPrinter = pQueue->hPrinter; pPrinter = pQueue->pPrinter; } else { pServerContext = (PSERVER_CONTEXT)pMDIWinInfo->pContext; pPrinter = pServerContext->pSelPrinter;
if( pPrinter ) OpenPrinterForSpecifiedAccess( pPrinter->pPrinterName, &hPrinter, PRINTER_ALL_ACCESS, NULL ); }
if( pPrinter && hPrinter ) { if(!SetPrinter(hPrinter, 0, NULL, bPause ? PRINTER_CONTROL_PAUSE : PRINTER_CONTROL_RESUME)) { ErrorOccurred = TRUE;
CheckTBButton(bPause ? IDM_PRINTER_RESUME : IDM_PRINTER_PAUSE);
if( bPause ) ReportFailure( hWnd, IDS_INSUFFPRIV_PAUSEPRINTER, IDS_COULDNOTPAUSEPRINTER ); else ReportFailure( hWnd, IDS_INSUFFPRIV_RESUMEPRINTING, IDS_COULDNOTRESUMEPRINTING ); }
if( pMDIWinInfo->WindowType == MDIWIN_SERVER ) { ClosePrinter( hPrinter ); }
// /* For Printer windows, add or remove " - Paused" from the titlebar:
// */
// else if( !ErrorOccurred )
// {
// SetPrinterTitle( hwndChild, pQueue->pPrinterName,
// ( bPause
// ? PRINTER_STATUS_PAUSED : 0 ) );
// }
// Force a refresh of the queue window until spooler sends messages
// back to PrintMan
if( !ErrorOccurred ) CheckTBButton(bPause ? IDM_PRINTER_PAUSE : IDM_PRINTER_RESUME);
// UpdateStatus((HWND)SendMessage(hwndClient, WM_MDIGETACTIVE, 0, 0L));
}
LEAVE_PROTECTED_DATA( pMDIWinInfo );
return 0; }
/*
* */ BOOL SetPrinterTitle( HWND hwnd, PTCHAR pPrinterName, DWORD Status ) { TCHAR Title[80]; TCHAR StatusString[40]; PTCHAR pTitle;
if( Status ) { GetPrinterStatusString( Status, StatusString );
_stprintf( Title, szTitleFormat, pPrinterName, StatusString ); pTitle = Title; } else pTitle = pPrinterName;
return SetWindowText( hwnd, pTitle ); }
/* SetMDITitle
* * Sets the title, appending status information where appropriate. * */ BOOL SetMDITitle( HWND hwnd, PMDIWIN_INFO pInfo ) { TCHAR Title[80]; TCHAR StatusString[40];
if( pInfo->WindowType != MDIWIN_SERVER ) { PQUEUE pPrinterContext = pInfo->pContext; LPPRINTER_INFO_2 pPrinter;
if( pPrinter = pPrinterContext->pPrinter ) { if( !pPrinter->pPrinterName ) { /* This should not happen!!
* (It did.) */ DBGMSG( DBG_WARNING, ( "SetMDITitle for %ws called with NULL pPrinter->pPrinterName\n", pPrinterContext->pPrinterName ) ); return FALSE; }
/* Check whether the printer name has changed,
* and, if so, update it: */ if( _tcscmp( pPrinterContext->pPrinterName, pPrinter->pPrinterName ) ) { //
// We need to remove the old connection for remote cases
// (true connections only).
//
// It should do a rename, since at some later time we
// may want to store info like "created at 10:00."
//
//
if (pInfo->WindowType == MDIWIN_NETWORKPRINTER) {
DeletePrinterConnection(pPrinterContext->pPrinterName); AddPrinterConnection(pPrinter->pPrinterName); }
ReallocSplStr( &pPrinterContext->pPrinterName, pPrinter->pPrinterName ); }
/* There is some information for this printer:
*/ if( pPrinter->Status ) { GetPrinterStatusString( pPrinter->Status, StatusString ); _stprintf( Title, szTitleFormat, pPrinterContext->pPrinterName, StatusString ); }
else { _tcscpy( Title, pPrinter->pPrinterName ); } }
else { if( pPrinterContext->Error == ERROR_ACCESS_DENIED ) GetPrinterStatusString( PRINTER_STATUS_ACCESS_DENIED, StatusString ); else GetPrinterStatusString( PRINTER_STATUS_UNKNOWN, StatusString );
_stprintf( Title, szTitleFormat, pPrinterContext->pPrinterName, StatusString ); } }
else { PSERVER_CONTEXT pServerContext = pInfo->pContext; LPTSTR pServerViewerTitle; TCHAR TempTitle[80];
/* Get "Server: %s":
*/ pServerViewerTitle = GetString( IDS_SERVERVIEWERTITLE );
if( pServerContext->Error ) { _stprintf( TempTitle, pServerViewerTitle, pServerContext->pServerName );
GetPrinterStatusString( PRINTER_STATUS_UNKNOWN, StatusString );
_stprintf( Title, szTitleFormat, TempTitle, StatusString ); }
else { _stprintf( Title, pServerViewerTitle, pServerContext->pServerName ); }
FreeSplStr( pServerViewerTitle ); }
return SetWindowText( hwnd, Title ); }
/*
* */ LONG FrameCommandPurgePrinter(HWND hWnd) { HWND hwndChild; PMDIWIN_INFO pMDIWinInfo; PQUEUE pQueue;
// Delete all the documents in the active window
hwndChild = (HWND) SendMessage(hwndClient, WM_MDIGETACTIVE, 0, 0L);
if (!hwndChild) return 0;
pMDIWinInfo = GETMDIWIN( hwndChild );
if( pMDIWinInfo->WindowType == MDIWIN_SERVER ) return 0;
ENTER_PROTECTED_DATA( pMDIWinInfo );
pQueue = GETQUEUE( hwndChild );
if( Message( hWnd, MSG_CONFIRMATION, IDS_PRINTMANAGER, IDS_DELETEALLPRINTJOBS_S, pQueue->pPrinterName ) == IDOK ) { if( !SetPrinter(pQueue->hPrinter, 0, NULL, PRINTER_CONTROL_PURGE)) { ReportFailure( hWnd, IDS_INSUFFPRIV_PURGEPRINTER, IDS_COULDNOTPURGEPRINTER ); } else { EnableCheckTBButtons(hwndChild); UpdateStatus(hwndChild); } }
LEAVE_PROTECTED_DATA( pMDIWinInfo );
return 0; }
/*
* */ LONG FrameCommandForms(HWND hWnd) { HWND hwndChild; PMDIWIN_INFO pMDIWinInfo; PQUEUE pQueue; PSERVER_CONTEXT pServerContext; PPRINTER_INFO_2 pPrinter; FORMS_DLG_DATA FormsDlgData; PRINTER_DEFAULTS PrinterDefaults = { NULL, NULL, SERVER_ALL_ACCESS }; HANDLE hServer = NULL;
hwndChild = (HWND) SendMessage(hwndClient, WM_MDIGETACTIVE, 0, 0L);
if (!hwndChild) return 0;
pMDIWinInfo = GETMDIWIN( hwndChild );
ZERO_OUT( &FormsDlgData );
if( pMDIWinInfo->WindowType != MDIWIN_SERVER ) { pQueue = (PQUEUE)pMDIWinInfo->pContext; FormsDlgData.pServerName = NULL; FormsDlgData.hPrinter = pQueue->hPrinter;
if( pQueue->pServerName ) { if (OpenPrinter(pQueue->pServerName, &hServer, &PrinterDefaults)) {
FormsDlgData.AccessGranted = SERVER_ACCESS_ADMINISTER;
} else {
FormsDlgData.AccessGranted = 0; } }
else FormsDlgData.AccessGranted = LocalPermission; } else {
pServerContext = (PSERVER_CONTEXT)pMDIWinInfo->pContext; pPrinter = pServerContext->pSelPrinter;
if( pPrinter ) OpenPrinterForSpecifiedAccess( pPrinter->pPrinterName, &FormsDlgData.hPrinter, PRINTER_READ, NULL );
FormsDlgData.pServerName = pServerContext->pServerName;
if( OpenPrinter( pServerContext->pServerName, &hServer, &PrinterDefaults ) ) { FormsDlgData.AccessGranted = SERVER_ACCESS_ADMINISTER; } }
if( FormsDlgData.hPrinter ) { SetCursor( hcursorWait );
DialogBoxParam( hInst, MAKEINTRESOURCE( DLG_FORMS ), hWnd, (DLGPROC)FormsDlg, (DWORD)&FormsDlgData );
if( pMDIWinInfo->WindowType == MDIWIN_SERVER ) { ClosePrinter( FormsDlgData.hPrinter );
}
if( hServer ) { ClosePrinter( hServer ); } } return 0; }
/* Invoke a network browse dialog to set the focus on a
* particular computer */ LONG FrameCommandServerViewer(HWND hwnd) { HANDLE hLibrary; LPFNI_SYSTEMFOCUSDIALOG lpfnI_SFD; WCHAR ServerName[UNCLEN+1]; BOOL fOK; DWORD Error; HWND hwndActive; PMDIWIN_INFO pMDIWinInfo;
SetCursor( hcursorWait );
lpfnI_SFD = (LPFNI_SYSTEMFOCUSDIALOG)LoadLibraryGetProcAddress( hwnd, szNtLanMan, szI_SystemFocusDialog, &hLibrary);
if(lpfnI_SFD) { Error = (*lpfnI_SFD)(hwnd, FOCUSDLG_SERVERS_ONLY | FOCUSDLG_BROWSE_ALL_DOMAINS, (LPWSTR)ServerName, sizeof(ServerName)/sizeof(WCHAR), &fOK, szLPrintManHlp, ID_HELP_SERVERVIEWER );
SetCursor( hcursorWait );
if( Error == NO_ERROR ) { if( fOK ) { PRINTER_DEFAULTS PrinterDefaults = { NULL, NULL, SERVER_ALL_ACCESS }; HANDLE hServer = NULL;
/* Convert the string we received from NETUI to ANSI:
*/ wsprintf( ServerName, TEXT("%ls"), ServerName );
//
// Attempt to open the server. Trap the ERROR_ACCESS_DENIED
// error so that we can open servers that exist but
// we don't have auto-refresh access to.
//
if( !OpenPrinter( ServerName, &hServer, &PrinterDefaults ) ) { LPTSTR pErrorString; DWORD dwError;
dwError = GetLastError();
//
// Special case this error code into a success
// case, with hServer == -1 to indicate a failed
// OpenPrinter.
//
if (dwError == ERROR_ACCESS_DENIED) { hServer = (HANDLE)-1; goto CreateServer; }
pErrorString = GetErrorString( GetLastError( ) );
Message( hwnd, MSG_ERROR, IDS_PRINTMANAGER, IDS_COULDNOTGETSERVERINFO, ServerName, pErrorString );
FreeSplStr( pErrorString ); } else { CreateServer: CreateServerWindow( hwnd, ServerName, hServer ); } } }
FreeLibrary(hLibrary);
}
hwndActive = (HWND)SendMessage(hwndClient, WM_MDIGETACTIVE, 0, 0L);
if( hwndActive ) { pMDIWinInfo = GETMDIWIN( hwndActive );
ENTER_PROTECTED_DATA( pMDIWinInfo ); UpdateStatus(hwndActive); EnableCheckTBButtons(hwndActive); LEAVE_PROTECTED_DATA( pMDIWinInfo ); }
SetCursor( hcursorArrow );
return 0; }
/*
* */ #ifdef LATER
LONG FrameCommandChangePrinter(HWND hWnd) { HWND hwndChild; PQUEUE pQueue;
hwndChild = (HWND) SendMessage(hwndClient, WM_MDIGETACTIVE, 0, 0L);
if (!hwndChild) return 0;
pQueue = GETQUEUE( hwndChild );
if (DialogBoxParam(hInst, TEXT("PRINTER"), hWnd, (DLGPROC)PrinterDlg, (DWORD)pQueue) == IDOK) { if (pQueue->RedoPrinterProperties) { PrinterProperties(hWnd, pQueue->hPrinter);
pQueue->RedoPrinterProperties = FALSE; } }
return 0; } #endif /* LATER */
/*
* */ LONG FrameCommandRemoveDoc(HWND hWnd) { HWND hwndChild; PQUEUE pQueue;
// Delete the selected document in the active window
hwndChild = (HWND) SendMessage(hwndClient, WM_MDIGETACTIVE, 0, 0L);
if (!hwndChild) return 0;
if( ( GETMDIWIN( hwndChild ) )->WindowType == MDIWIN_SERVER ) return 0;
pQueue = GETQUEUE( hwndChild );
if( DeleteQJ(hwndChild, pQueue) != 0 ) { ReportFailure( hWnd, IDS_INSUFFPRIV_DELETEDOCUMENT, IDS_COULDNOTREMOVEDOCUMENT ); }
// Force a refresh of the queue window until spooler sends messages
// back to PrintMan
EnableCheckTBButtons(hwndChild); // UpdateStatus((HWND)SendMessage(hwndClient, WM_MDIGETACTIVE, 0, 0L));
return 0; }
/*
* */ LONG FrameCommandDocDetails(HWND hWnd) { HWND hwndChild; PMDIWIN_INFO pMDIWinInfo; PQUEUE pQueue;
// Invoke the document details dialog for selected doc in active window
hwndChild = (HWND) SendMessage(hwndClient, WM_MDIGETACTIVE, 0, 0L);
if (!hwndChild) return 0;
pMDIWinInfo = GETMDIWIN( hwndChild );
if( pMDIWinInfo->WindowType == MDIWIN_SERVER ) return 0;
ENTER_PROTECTED_DATA( pMDIWinInfo );
pQueue = GETQUEUE( hwndChild );
if (pQueue->pSelJob == NULL){ goto Done; }
SetCursor( hcursorWait );
DialogBoxParam (hInst, MAKEINTRESOURCE(DLG_DOCTAILS), hWnd, (DLGPROC)DocDetailsDlg, (DWORD)pQueue);
SetCursor( hcursorArrow );
Done:
LEAVE_PROTECTED_DATA( pMDIWinInfo );
return 0; }
/*
* */ LONG FrameCommandDocumentPauseResume(HWND hWnd, WORD PauseResume) { HWND hwndChild; PMDIWIN_INFO pMDIWinInfo; PQUEUE pQueue;
DBG_UNREFERENCED_PARAMETER(hWnd);
hwndChild = (HWND) SendMessage(hwndClient, WM_MDIGETACTIVE, 0, 0L);
if (!hwndChild) return 0;
pMDIWinInfo = GETMDIWIN( hwndChild );
if( pMDIWinInfo->WindowType != MDIWIN_SERVER ) { ENTER_PROTECTED_DATA( pMDIWinInfo );
pQueue = (PQUEUE)pMDIWinInfo->pContext;
if( !pQueue->pSelJob ) { /* This shouldn't happen, but did once!
*/ DBGMSG( DBG_WARNING, ( "FrameCommandDocumentPauseResume called with no job selected" ) ); }
else if (!SetJob(pQueue->hPrinter, pQueue->pSelJob->JobId, 0, NULL, ( ( pQueue->pSelJob->Status & JOB_STATUS_PAUSED ) ? JOB_CONTROL_RESUME : JOB_CONTROL_PAUSE ) ) ) { CheckTBButton( ( PauseResume == IDM_DOCUMENT_PAUSE ) ? IDM_DOCUMENT_RESUME : IDM_DOCUMENT_PAUSE );
if( PauseResume == IDM_DOCUMENT_PAUSE ) ReportFailure( hWnd, IDS_INSUFFPRIV_PAUSEDOCUMENT, IDS_COULDNOTPAUSEDOCUMENT ); else ReportFailure( hWnd, IDS_INSUFFPRIV_RESUMEDOCUMENT, IDS_COULDNOTRESUMEDOCUMENT ); }
else CheckTBButton(PauseResume);
LEAVE_PROTECTED_DATA( pMDIWinInfo ); } return 0; }
/*
* */ LONG FrameCommandRestart(HWND hWnd) { HWND hwndChild; PMDIWIN_INFO pMDIWinInfo; PQUEUE pQueue;
hwndChild = (HWND) SendMessage(hwndClient, WM_MDIGETACTIVE, 0, 0L);
if (!hwndChild) return 0;
pMDIWinInfo = GETMDIWIN( hwndChild );
if( pMDIWinInfo->WindowType == MDIWIN_SERVER ) return 0;
pQueue = GETQUEUE( hwndChild );
if( pQueue->SelJobId ) { ENTER_PROTECTED_DATA( pMDIWinInfo );
// Cancel the print job
if( !SetJob( pQueue->hPrinter, pQueue->SelJobId, 0, NULL, JOB_CONTROL_RESTART ) ) { ReportFailure( hWnd, IDS_INSUFFPRIV_RESTARTDOCUMENT, IDS_COULDNOTRESTARTDOCUMENT ); }
LEAVE_PROTECTED_DATA( pMDIWinInfo ); }
// Force a refresh of the queue window until spooler sends messages
// back to PrintMan
EnableCheckTBButtons(hwndChild);
return 0; }
/*
* */ LONG FrameCommandFont(HWND hWnd) { return 0;
UNREFERENCED_PARAMETER(hWnd); }
/*
* */ LONG FrameCommandRefreshRate(HWND hWnd) { return 0;
UNREFERENCED_PARAMETER(hWnd); }
/*
* */ LONG FrameCommandToolbar(HWND hWnd) { RECT rc;
bToolBar = !bToolBar;
ShowWindow( hwndToolbar, bToolBar ? SW_SHOW : SW_HIDE );
GetClientRect(hwndFrame, &rc); SendMessage(hwndFrame, WM_SIZE, SIZENORMAL, MAKELONG(rc.right, rc.bottom)); InvalidateRect(hwndFrame, NULL, TRUE);
CheckMenuItem(GetMenu(hWnd), IDM_TOOLBAR, MF_BYCOMMAND | (bToolBar ? MF_CHECKED : MF_UNCHECKED));
return 0; }
/*
* */ LONG FrameCommandStatusbar(HWND hWnd) { PMDIWIN_INFO pInfo; HWND hwndChild; RECT rc;
hwndChild = (HWND) SendMessage(hwndClient, WM_MDIGETACTIVE, 0, 0L); bStatusBar = !bStatusBar;
ShowWindow( hwndStatus, bStatusBar ? SW_SHOW : SW_HIDE );
GetClientRect(hwndFrame, &rc); SendMessage(hwndFrame, WM_SIZE, SIZENORMAL, MAKELONG(rc.right, rc.bottom));
if( pInfo = GETMDIWIN( hwndChild ) ) { ENTER_PROTECTED_DATA( pInfo ); UpdateStatus(hwndChild); LEAVE_PROTECTED_DATA( pInfo ); }
InvalidateRect(hwndFrame, NULL, TRUE);
CheckMenuItem(GetMenu(hWnd), IDM_STATUSBAR, MF_BYCOMMAND | (bStatusBar ? MF_CHECKED : MF_UNCHECKED));
return 0; }
/*
* */ LONG FrameCommandSaveSettings(HWND hWnd) { bSaveSettings = !bSaveSettings;
CheckMenuItem(GetMenu(hWnd), IDM_SAVESETTINGS, MF_BYCOMMAND | (bSaveSettings ? MF_CHECKED : MF_UNCHECKED));
return 0; }
/*
* */ LONG FrameCommandPermissions(HWND hWnd) { HWND hwndChild; PMDIWIN_INFO pInfo;
hwndChild = (HWND) SendMessage(hwndClient, WM_MDIGETACTIVE, 0, 0L);
if( hwndChild ) { pInfo = GETMDIWIN( hwndChild );
if( pInfo->WindowType != MDIWIN_SERVER ) { ENTER_PROTECTED_DATA( pInfo ); ENTER_PROTECTED_HANDLE( pInfo ); ResetEvent( pInfo->RefreshSignal );
CallDiscretionaryAclEditor( hWnd, pInfo->pContext );
SetEvent( pInfo->RefreshSignal ); LEAVE_PROTECTED_HANDLE( pInfo ); LEAVE_PROTECTED_DATA( pInfo ); } }
return 0; }
/*
* */ LONG FrameCommandAuditing(HWND hWnd) { HWND hwndChild; PMDIWIN_INFO pInfo;
hwndChild = (HWND) SendMessage(hwndClient, WM_MDIGETACTIVE, 0, 0L);
if( hwndChild ) { pInfo = GETMDIWIN( hwndChild );
if( pInfo->WindowType != MDIWIN_SERVER ) { ENTER_PROTECTED_DATA( pInfo ); ENTER_PROTECTED_HANDLE( pInfo ); ResetEvent( pInfo->RefreshSignal );
CallSystemAclEditor( hWnd, pInfo->pContext );
SetEvent( pInfo->RefreshSignal ); LEAVE_PROTECTED_HANDLE( pInfo ); LEAVE_PROTECTED_DATA( pInfo ); } }
return 0; }
/*
* */ LONG FrameCommandOwner(HWND hWnd) { HWND hwndChild; PMDIWIN_INFO pInfo;
hwndChild = (HWND) SendMessage(hwndClient, WM_MDIGETACTIVE, 0, 0L);
if( hwndChild ) { pInfo = GETMDIWIN( hwndChild );
if( pInfo->WindowType != MDIWIN_SERVER ) { ENTER_PROTECTED_DATA( pInfo ); ENTER_PROTECTED_HANDLE( pInfo ); ResetEvent( pInfo->RefreshSignal );
CallTakeOwnershipDialog( hWnd, pInfo->pContext );
SetEvent( pInfo->RefreshSignal ); LEAVE_PROTECTED_HANDLE( pInfo ); LEAVE_PROTECTED_DATA( pInfo ); } }
return 0; }
/*
* */ VOID FrameCommandRefresh(HWND hWnd) { HWND hwndChild; PMDIWIN_INFO pMDIWinInfo;
hwndChild = (HWND) SendMessage(hwndClient, WM_MDIGETACTIVE, 0, 0L);
if( hwndChild ) { pMDIWinInfo = GETMDIWIN( hwndChild );
Refresh( hwndChild, pMDIWinInfo, REPAINT_FORCE ); }
UNREFERENCED_PARAMETER( hWnd ); }
/*
* */ LONG FrameCommandClose(HWND hWnd) { HWND hwndChild;
DBG_UNREFERENCED_PARAMETER(hWnd);
hwndChild = (HWND) SendMessage(hwndClient, WM_MDIGETACTIVE, 0, 0L);
if (!hwndChild) return 0;
if (SendMessage(hwndChild, WM_QUERYENDSESSION, 0, 0L)) SendMessage(hwndClient, WM_MDIDESTROY, (WPARAM) hwndChild, 0L);
return 0; }
LONG FrameCommandReturn() { HWND hwndActive;
hwndActive = (HWND)SendMessage(hwndClient, WM_MDIGETACTIVE, 0, 0L);
if (hwndActive && IsIconic(hwndActive)) {
SendMessage(hwndActive, WM_SYSCOMMAND, SC_RESTORE, 0L);
} else {
PMDIWIN_INFO pInfo;
pInfo = GETMDIWIN(hwndActive);
if( !pInfo ) return 0;
//
// If there's nothing selected or we're in the middle
// of a drag operation, don't do anything:
//
if( ( pInfo->ObjSelected == NOSELECTION ) ||( pInfo->DragPosition != NOSELECTION ) ) { } else {
//
// Do the same as double-click:
//
MDICommandObjListDblClk( hwndActive ); } } return 0; }
/*
* */ LONG FrameCommandAbout(HWND hWnd) { TCHAR Title[RESOURCE_STRING_LENGTH];
SetCursor( hcursorWait );
LoadString( hInst, IDS_PRINTMANAGER, Title, sizeof Title / sizeof *Title );
ShellAbout( hWnd, Title, NULL, hiconPrinter );
SetCursor( hcursorArrow );
return 0; }
/*
* */ VOID FrameCommandDefaultPrinter(HWND hwnd, WORD Command) { switch (Command) { case CBN_SELCHANGE: ToolbarCommandSelChange(FALSE); break;
/* F1 will bring up help on the Default Printer list,
* if it has the focus: */ case CBN_SETFOCUS: WinHelpMenuID = ID_HELP_DEFAULT_PRINTER; break;
case CBN_KILLFOCUS: WinHelpMenuID = 0; break; } }
/* Handle notification codes from the toolbar.
* Set the status bar help in response to TBN_BEGIN/ENDDRAG. */ VOID FrameCommandToolbarNotify( HWND hwnd, WPARAM wParam, LPARAM lParam ) { MenuHelp( WM_COMMAND, wParam, lParam, GetMenu( hwnd ), hInst, hwndStatus, pMenuHelpIDs );
WinHelpMenuID = (DWORD)LOWORD( wParam ); }
/* Cause tab to toggle between the default printer list and the active
* MDI window, so that the keyboard can be used to select default printer. */ VOID FrameCommandTab(HWND hwnd) { HWND hwndActiveMDI; PMDIWIN_INFO pMDIWinInfo; HWND hwndFocus;
hwndActiveMDI = (HWND) SendMessage(hwndClient, WM_MDIGETACTIVE, 0, 0L);
if( hwndActiveMDI ) { pMDIWinInfo = GETMDIWIN( hwndActiveMDI );
hwndFocus = GetFocus( );
if( hwndFocus == pMDIWinInfo->hwndList ) SetFocus( hwndPrinterList ); else SetFocus( pMDIWinInfo->hwndList ); } }
/*
* */ LONG FrameCommandDefault(HWND hWnd, WPARAM wParam, LONG lParam) { HWND hwndChild;
hwndChild =(HWND) SendMessage(hwndClient, WM_MDIGETACTIVE, 0, 0L);
if (!hwndChild) return 0;
if (IsWindow(hwndChild)) SendMessage(hwndChild, WM_COMMAND, wParam, lParam);
// Pass unprocessed WM_COMMAND messages to DefFrameProc
return DefFrameProc(hWnd, hwndClient, WM_COMMAND, wParam, lParam); }
/*
* */ VOID FrameSysColorChange( ) { DWORD OldSysColorHighlight; DWORD OldSysColorHighlightText; DWORD OldSysColorWindow; DWORD OldSysColorBtnFace; DWORD OldSysColorBtnText; DWORD OldSysColorBtnHighlight; DWORD OldSysColorBtnShadow;
OldSysColorHighlight = SysColorHighlight; OldSysColorHighlightText = SysColorHighlightText; OldSysColorWindow = SysColorWindow; OldSysColorBtnFace = SysColorBtnFace; OldSysColorBtnText = SysColorBtnText; OldSysColorBtnHighlight = SysColorBtnHighlight; OldSysColorBtnShadow = SysColorBtnShadow;
GetSystemColors( );
/* If the higlight or window colour has changed,
* we must fix up the bitmaps again. * The easiest way to do this is by deleting the old stuff * and reload the bitmaps from resources: */ if( ( OldSysColorHighlight != SysColorHighlight ) ||( OldSysColorWindow != SysColorWindow ) ) { SelectObject( hdcMem, hbmDefault );
DeleteObject( hbmBitmaps ); DeleteDC( hdcMem );
LoadBitmaps( ); } }
/* RepaintWindow
* * Callback function passed to EnumChildWindows by FrameWinIniChange. * It is called on each MDI window in the event that international * time formats might have changed. * Enumeration continues while this function returns TRUE. * * Parameters: * * hwnd - The child window's handle * * lparam - Application-defined value (unused) * * * Return: * * The return code from InvalidateRect * */ BOOL CALLBACK RepaintWindow( HWND hwnd, LPARAM lparam ) { UNREFERENCED_PARAMETER( lparam );
/* Repaint only windows with ID == ID_OBJLIST,
* i.e. the document lists in printer windows * and printer lists in server windows: */ if( GetWindowLong( hwnd, GWL_ID ) == ID_OBJLIST ) return InvalidateRect( hwnd, NULL, TRUE ); else return TRUE; }
/* FrameWinIniChange
* * Called in response to WM_WININICHANGE. * If the section that has been changed is "intl", or if we don't know * because NULL was passed (frowned upon but permitted), * cause the child windows to be repainted so that any time values * will be repainted. * E.g., if the user has sensibly changed the time format from 12-hour * to 24-hour, we want to repaint any times. * * Parameters: * * hwnd - The frame window handle * * pSection - A pointer to string specifying the section in the INI * file that has changed. If this is NULL, play it safe, * and assume that something might have changed. * */ VOID FrameWinIniChange( HWND hwnd, LPTSTR pSection ) { TCHAR Buffer[MAX_PATH]; PTCHAR pPrinterName; INT iNewDefaultPrinter;
if( ( pSection == NULL ) ||( _tcsicmp( pSection, szInternational ) == 0 ) ) { InitializeInternationalTimeConstants( );
EnumChildWindows( hwnd, (WNDENUMPROC)RepaintWindow, (LPARAM)0 ); }
/* If an application has changed the windows.device section in
* WIN.INI, update the default printer: */ if( ( pSection == NULL ) ||( _tcsicmp( pSection, TEXT("device") ) == 0 ) ) { if( GetProfileString( szWindows, szDevice, TEXT(""), Buffer, sizeof Buffer ) ) { pPrinterName = _tcstok( Buffer, TEXT(",") );
if( pPrinterName ) { iNewDefaultPrinter = SendMessage( hwndPrinterList, CB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)pPrinterName );
if( iNewDefaultPrinter != CB_ERR ) { if( SendMessage( hwndPrinterList, CB_SETCURSEL, (WPARAM)iNewDefaultPrinter, 0 ) == CB_ERR ) { DBGMSG( DBG_WARNING, ( "Failed to set new default printer\n" ) ); } } else { DBGMSG( DBG_WARNING, ( "An application updated WIN.INI with an unknown Windows Device\n" ) ); } } else { DBGMSG( DBG_WARNING, ( "An application updated WIN.INI with a NULL Windows Device\n" ) ); } } else { DBGMSG( DBG_WARNING, ( "GetProfileString failed: Error %d\n", GetLastError( ) ) ); } } }
/* We get here when the thread monitoring the local server detects that
* a printer has been added. This may be because we've just added one, * however it might also be because someone added one remotely. * If we added it, we should have set the global PrinterAdded = TRUE. * Otherwise we enumerate the printers and figure out which was new, * then create an iconised window for the new printer. */ VOID FramePrinterAdded( HWND hwnd, DWORD dwType) { PPRINTER_INFO_4 pPrinters = NULL; DWORD cbPrinters = 0; DWORD cPrinters; LPTSTR pServerName = NULL; LPTSTR pPrinterName = NULL; DWORD i; PQUEUE pQueue;
if( PrinterAdded ) { /* We're expecting this, so forget it:
*/ PrinterAdded = FALSE; return; }
DBGMSG( DBG_TRACE, ( "A printer was added\n" ) );
if( ENUM_PRINTERS( dwType ? PRINTER_ENUM_LOCAL : PRINTER_ENUM_CONNECTIONS, pServerName, 4, pPrinters, cbPrinters, &cbPrinters, &cPrinters ) ) { for( i = 0; i < cPrinters; i++ ) { if( !FindPrinterWindow( pPrinters[i].pPrinterName ) ) { DBGMSG( DBG_TRACE, ( "Creating new printer: %s\n", pPrinters[i].pPrinterName ) );
if( pQueue = AllocQueue( pPrinters[i].pPrinterName ) ) { pQueue->Error = OpenThreadObject(pQueue->pPrinterName, &pQueue->hPrinter, &pQueue->AccessGranted, MDIWIN_PRINTER); if( !pQueue->Error ) { DWORD Flags = CREATE_PRINTER_ICONIC; HWND hwnd;
if( pPrinters[i].Attributes & PRINTER_ATTRIBUTE_SHARED ) Flags |= CREATE_PRINTER_SHARED;
hwnd = CreateQueueWindow( hwnd, pQueue, PRINTER_STATUS_LOADING, dwType ? MDIWIN_LOCALPRINTER : MDIWIN_NETWORKPRINTER, Flags );
BringWindowToTop( hwnd ); FlashWindow( hwnd, FALSE ); } else { FreeQueue( pQueue ); } } } }
FreeSplMem( pPrinters ); }
else { DBGMSG( DBG_WARNING, ( "EnumPrinters failed: Error %d\n", GetLastError( ) ) ); } }
/* FrameRegNotifyChangeKeyValue
* * This routine will be called via a message posted from the main * message dispatch loop when a change is made to the device key * of the windows section in the registry WIN.INI mapping. * This may be because an application has changed the default printer. * We check whether this is the case by querying that value, parsing * out the comma following the printer name in the entry, and ensuring * that this is the current default printer. * Hoping for a WM_WININICHANGE is not very reliable, since some apps * (e.g. Lotus Improv) don't appear to broadcast it when they change * WIN.INI. * * Parameters: * * hwnd - The frame window handle * * hWindowsKey - An open key to the registry WIN.INI mapping * * * Note there is some redundancy here, since this will also be called * if the user selects the default printer from Print Manager. * This could be avoided by our setting a flag when we have caused * the default printer to change. * * * AndrewBe, 15 June 1993 * */ VOID FrameRegNotifyChangeKeyValue( HWND hwnd, HKEY hWindowsKey ) { DWORD Status; TCHAR Buffer[MAX_PATH]; PTCHAR pPrinterName; INT iNewDefaultPrinter; DWORD BufferSize;
BufferSize = sizeof Buffer*sizeof(TCHAR);
if( ( Status = RegQueryValueEx( hWindowsKey, szDevice, REG_OPTION_RESERVED, NULL, (LPBYTE)Buffer, &BufferSize ) ) == NO_ERROR) { /* Hack out the comma from the buffer,
* which strtok helpfully does for us: */ pPrinterName = _tcstok( Buffer, TEXT(",") );
if( pPrinterName ) { iNewDefaultPrinter = SendMessage( hwndPrinterList, CB_FINDSTRING, (WPARAM)-1, (LPARAM)pPrinterName );
if( iNewDefaultPrinter != CB_ERR ) { if( SendMessage( hwndPrinterList, CB_SETCURSEL, (WPARAM)iNewDefaultPrinter, 0 ) == CB_ERR ) { DBGMSG( DBG_WARNING, ( "Failed to set new default printer\n" ) ); } } else { DBGMSG( DBG_WARNING, ( "An application updated WIN.INI with an unknown Windows Device\n" ) ); } } else { DBGMSG( DBG_WARNING, ( "An application updated WIN.INI with a NULL Windows Device\n" ) ); } } else { DBGMSG( DBG_WARNING, ( "RegQueryValuEx failed: Error %d\n", Status ) ); }
}
/*
* END OF ROUTINES CALLED BY FrameWndProc */
//////////////////////////////////////////////////////////////////////
//
// UpdateStatus
//
// Load the status buffers with the appropriate stuff and invalidates
// the status area causing it to repaint.
//
// Updates the three global status strings for the currently active
// child window.
//
// strStatusName
// strStatusStatus
// strStatusWaiting
//
//////////////////////////////////////////////////////////////////////
VOID UpdateStatus( HWND hWnd ) { PMDIWIN_INFO pMDIWinInfo; PVOID pContext; LPPRINTER_INFO_2 pPrinter; LPJOB_INFO_2 pJobSelected; DWORD JobSelected; TCHAR szTemp[128]; LPTSTR pServerName = NULL; /* Non-null for server windows */ DWORD Error;
if (!bStatusBar) return;
/* If hWnd is NULL, clear the status bar,
* otherwise get the active MDI window: */ if( !hWnd || !(hWnd = (HWND)SendMessage(hwndClient, WM_MDIGETACTIVE, 0, 0L))) { *strStatusName = NULLC; *strStatusStatus = NULLC; *strStatusWaiting = NULLC; }
else { if( !( pMDIWinInfo = GETMDIWIN( hWnd ) ) ) { return; }
ENTER_PROTECTED_DATA(pMDIWinInfo);
pContext = pMDIWinInfo->pContext;
if( pMDIWinInfo->WindowType != MDIWIN_SERVER ) { pPrinter = ( (PQUEUE)pContext )->pPrinter; pJobSelected = ( (PQUEUE)pContext )->pSelJob; JobSelected = pMDIWinInfo->ObjSelected; Error = ( (PQUEUE)pContext )->Error; } else { pPrinter = ( (PSERVER_CONTEXT)pContext )->pSelPrinter; pJobSelected = NULL; JobSelected = NOSELECTION; Error = ( (PSERVER_CONTEXT)pContext )->Error; }
if( pMDIWinInfo->WindowType == MDIWIN_SERVER ) { pServerName = ( (PSERVER_CONTEXT)pContext )->pServerName;
/* No job info for Server Viewer - should we show something?
*/ if( IsIconic( hWnd ) ) _tcscpy( strStatusName, pServerName ); else { if( pPrinter && pPrinter->pPrinterName ) _tcscpy( strStatusName, pPrinter->pPrinterName ); else _tcscpy( strStatusName, pServerName ); } } else if( pPrinter ) { if( JobSelected != NOSELECTION ) { if( pJobSelected->pDocument && *pJobSelected->pDocument ) _tcscpy (strStatusName, pJobSelected->pDocument); else _tcscpy (strStatusName, strUntitled); } else if( ( (PQUEUE)pContext )->pPrinterName ) _tcscpy( strStatusName, ( (PQUEUE)pContext )->pPrinterName ); else *strStatusName = NULLC; } else if( ( (PQUEUE)pContext )->pPrinterName ) _tcscpy( strStatusName, ( (PQUEUE)pContext )->pPrinterName ); else *strStatusName = NULLC;
if( pServerName && IsIconic( hWnd ) ) { *strStatusWaiting = NULLC; *strStatusStatus = NULLC; } else if( pPrinter ) { if( ( pPrinter->cJobs == 0 ) || ( JobSelected == NOSELECTION ) ) { GetPrinterStatusString( pPrinter->Status, strStatusStatus );
LoadString (hInst, IDS_DOCUMENTSQUEUED_D, szTemp, sizeof(szTemp) / sizeof(*szTemp)); wsprintf (strStatusWaiting, szTemp, pPrinter->cJobs); } else { if( ( pJobSelected->pStatus ) && ( *pJobSelected->pStatus ) ) _tcsncpy (strStatusStatus, pJobSelected->pStatus, sizeof(strStatusStatus)/sizeof(TCHAR)-1); else GetJobStatusString( pJobSelected->Status, strStatusStatus );
LoadString (hInst, IDS_PAGESCOMPLETED_D, szTemp, sizeof(szTemp) / sizeof(*szTemp)); wsprintf (strStatusWaiting, szTemp, pJobSelected->TotalPages ); } } else { if (Error == ERROR_ACCESS_DENIED) {
GetPrinterStatusString( PRINTER_STATUS_ACCESS_DENIED, strStatusStatus ); } else { GetPrinterStatusString( PRINTER_STATUS_UNKNOWN, strStatusStatus ); }
*strStatusWaiting = NULLC; }
LEAVE_PROTECTED_DATA(pMDIWinInfo); }
// force the status area to update
SendMessage( hwndStatus, SB_SETTEXT, ISF_NAME, (LPARAM)strStatusName ); SendMessage( hwndStatus, SB_SETTEXT, ISF_STATUS, (LPARAM)strStatusStatus ); SendMessage( hwndStatus, SB_SETTEXT, ISF_WAITING, (LPARAM)strStatusWaiting );
}
BOOL InitApplication( HANDLE hInstance, LPHANDLE lphAccel ) { WNDCLASS wc; HCURSOR hcurArrow;
hInst = hInstance;
hcurArrow = LoadCursor(NULL, IDC_ARROW);
GetSystemColors( );
if (!LoadBitmaps()) return FALSE;
hiconPrinter = LoadIcon( hInstance, MAKEINTRESOURCE(IDI_PRINTMAN ) ); hiconServer = LoadIcon( hInstance, MAKEINTRESOURCE(IDI_SERVER ) ); hiconConnect = LoadIcon( hInstance, MAKEINTRESOURCE(IDI_CONNECT ) ); hiconShared = LoadIcon( hInstance, MAKEINTRESOURCE(IDI_SHARED ) );
// Register the main Print Manager frame window class
wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = FrameWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInst; wc.hIcon = hiconPrinter; wc.hCursor = hcurArrow; wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wc.lpszMenuName = szMenuClass; wc.lpszClassName = szPrintManagerClass;
if (!RegisterClass(&wc)) return FALSE;
// Register the Print Queue child window class
// You can't close a window of this class
// except if the corresponding printer is deleted.
// -------------------------------------------------------------------
// There is no icon defined for this class, since we want to change it
// based on whether the printer is shared or not.
// There is a user feature (for Win31 compatibility, apparently)
// which means that we can't do this by specifying an icon here
// then responding to the WM_PAINTICON message by calling DrawIcon,
// since somewhere in the guts of user it gets a zero-sized update
// region. So instead we don't define a default class icon,
// but put an icon handle in the MDI window's instance data,
// which we then use when we get a WM_PAINT message.
wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = MDIWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = sizeof(LONG); // GWL_PMDIWIN
wc.hInstance = hInst; wc.hIcon = NULL; // No icon -- put handle in MDIWinInfo
wc.hCursor = hcurArrow; wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wc.lpszMenuName = NULL; wc.lpszClassName = szChildClass;
if (!RegisterClass(&wc)) return FALSE;
*lphAccel = LoadAccelerators(hInst, TEXT("PrintManAccel"));
// Register window class for custom spinner dialog box control
if (!RegisterArrowClass (hInstance)) return FALSE;
return TRUE; }
BOOL InitQueueChildWindows( HWND hWnd) { PQUEUE pQueue; LPPRINTER_INFO_4 pPrinters = NULL; DWORD cbPrinters; DWORD cReturned = 0; DWORD i; TCHAR GettingPrinterInfo[80]; BOOL OK; DWORD Flags; DWORD WindowType;
DBGMSG( DBG_TRACE, ( "InitQueueChildWindows\n" ) )
cbPrinters = 0x1000;
if( !( pPrinters = AllocSplMem( cbPrinters ) ) ) cbPrinters = 0;
LoadString( hInst, IDS_GETTING_PRINTER_INFO, GettingPrinterInfo, sizeof GettingPrinterInfo / sizeof *GettingPrinterInfo ); SendMessage( hwndStatus, SB_SETTEXT, SBT_NOBORDERS|255, (LPARAM)GettingPrinterInfo ); SendMessage( hwndStatus, SB_SIMPLE, 1, 0L ); UpdateWindow( hwndStatus );
OK = ENUM_PRINTERS( PRINTER_ENUM_FAVORITE | PRINTER_ENUM_LOCAL, NULL, 4, pPrinters, cbPrinters, &cbPrinters, &cReturned );
DBGMSG( DBG_TRACE, ( "EnumPrinters returned %d printers\n", cReturned ) );
SetStatusMode( STATUS_MODE_NORMAL, FALSE );
if( !pPrinters && !OK ) { Message( hWnd, MSG_ERROR, IDS_PRINTMANAGER, IDS_COULDNOTENUMERATEPRINTERS );
SendMessage( hWnd, WM_CLOSE, 0, 0 );
return FALSE; }
// Process the list of printers returned by creating and initializing
// local data structures for these
for (i=0; i<cReturned; i++) { Flags = 0;
//
// We don't know if this printer is pending deletion,
// enumerate all of them.
//
DBGMSG( DBG_TRACE, ( "Initializing queue for %s\n", pPrinters[i].pPrinterName ) );
if( pQueue = AllocQueue(pPrinters[i].pPrinterName)) { if ( pPrinters[i].pServerName ) { pQueue->pServerName = AllocSplStr( pPrinters[i].pServerName ); if ( !pQueue->pServerName ) { //
// Fail... !! LATER !!
//
} } else { //
// Null implies a local printer
//
pQueue->pServerName = NULL; }
if( ALL_FLAGS_ARE_SET( pPrinters[i].Attributes, PRINTER_ATTRIBUTE_NETWORK | PRINTER_ATTRIBUTE_LOCAL ) ) WindowType = MDIWIN_LOCALNETWORKPRINTER; else if( pPrinters[i].Attributes & PRINTER_ATTRIBUTE_NETWORK ) WindowType = MDIWIN_NETWORKPRINTER; else WindowType = MDIWIN_LOCALPRINTER;
if( pPrinters[i].Attributes & PRINTER_ATTRIBUTE_SHARED ) Flags = CREATE_PRINTER_SHARED;
CreateQueueWindow( hWnd, pQueue, PRINTER_STATUS_LOADING, WindowType, Flags ); } }
if(cReturned == 0) EnableCheckTBButtons(NULL); else EnableCheckTBButtons((HWND)SendMessage(hwndClient, WM_MDIGETACTIVE, 0, 0L));
if( pPrinters ) FreeSplMem(pPrinters);
UpdateDefaultList();
return TRUE; }
BOOL InitServerChildWindows( HWND hwnd ) { EnumRegistryValues( szRegServers, (ENUMREGPROC)CreateServerWindow, (PVOID)hwnd );
UpdateDefaultList();
return TRUE; }
long APIENTRY MDIWndProc( HWND hWnd, UINT message, WPARAM wParam, LONG lParam ) { static POINT CursorPos;
if( message == WM_DragList ) { return MDIDragList( hWnd, (LPDRAGLISTINFO)lParam ); }
switch (message) {
case WM_CREATE: MDICreate( hWnd, lParam ); break;
case WM_PAINT: return MDIPaint(hWnd, wParam, lParam);
case WM_ERASEBKGND: if( MDIEraseBkgnd(hWnd, (HDC)wParam) ) return 1; break;
case WM_QUERYDRAGICON: return (long)MDIQueryDragIcon(hWnd);
case WM_MENUSELECT: return MDIMenuSelect( hWnd, wParam, lParam );
case WM_COMMAND: switch (WPARAM_ID(wParam)) { case ID_OBJLIST: switch (HIWORD(wParam)) { case LBN_SELCHANGE: MDICommandObjListSelChange(hWnd); break;
case LBN_DBLCLK: MDICommandObjListDblClk(hWnd); break; } break; }
return 0;
case WM_NOTIFY: { HD_NOTIFY * lpNot;
lpNot = (HD_NOTIFY *) lParam; switch (wParam) { case ID_HEADER: switch (lpNot->hdr.code) { case HDN_BEGINTRACK: MDICommandHeaderBeginDrag(hWnd, &CursorPos); break;
case HDN_TRACK: MDICommandHeaderDragging(hWnd, &CursorPos, lpNot); break;
case HDN_ENDTRACK: MDICommandHeaderEndDrag(hWnd, &CursorPos, lpNot); break; } break; } } return 0;
case WM_SYSCOMMAND: switch( wParam ) { case SC_CLOSE: if( !MDIClose(hWnd) ) { SendMessage(hWnd, WM_SYSCOMMAND, SC_MINIMIZE, lParam); return 0; } break; } break;
case WM_VKEYTOITEM: switch( LOWORD( wParam ) ) { case VK_SPACE: MDIVKeyToItemSpace(hWnd); return -2; // Means we handled everything
case VK_UP: case VK_DOWN: case VK_LEFT: case VK_RIGHT: if( MDIVKeyToItemUpDown(hWnd, LOWORD( wParam) ) == -2 ) return -2; break;
default: MDIVKeyToItemDefault(hWnd); break; } break;
case WM_PARENTNOTIFY: switch( wParam ) { case WM_RBUTTONDOWN: MDIParentNotifyRButtonDown( hWnd, lParam ); return 0; } break;
case WM_SIZE: MDISize( hWnd, (DWORD)lParam ); break; // WM_SIZE MUST also be processed by DefMDIChildProc
case WM_MDIACTIVATE: if (wParam) MDIMDIActivate( hWnd, (HWND)wParam, (HWND)lParam ); break;
case WM_NCACTIVATE: if( !wParam ) MDINCActivate( hWnd ); break;
case WM_WINDOWPOSCHANGED: return MDIWindowPosChanged( hWnd, wParam, lParam );
case WM_SETFOCUS: MDISetFocus( hWnd ); return 0;
case WM_MEASUREITEM: MDIMeasureItem( hWnd, (LPMEASUREITEMSTRUCT)lParam ); return 0;
case WM_DRAWITEM: MDIDrawItem( hWnd, (LPDRAWITEMSTRUCT)lParam ); return TRUE;
case WM_TIMER: // Update Print Jobs for this queue.
MDITimer( hWnd ); return 0;
case WM_STATUS_CHANGED: // MDIStatusChanged( hWnd );
return 0;
case WM_UPDATE_LIST: MDIUpdateList( hWnd ); return 0;
case SB_SETPARTS: MDISetParts( hWnd, wParam, lParam ); return 0;
#ifdef ALLOW_DROPS_ON_ALL_PRINTERS
case WM_DROPOBJECT: MDIDropObject( hWnd ); return 0x544E5250L; // 'PRNT' tells fm to print
#endif /* ALLOW_DROPS_ON_ALL_PRINTERS */
case WM_CLOSE: if( !MDIClose(hWnd) ) { SendMessage(hWnd, WM_SYSCOMMAND, SC_MINIMIZE, lParam); return 0; } break;
case WM_DESTROY: MDIDestroy( hWnd ); return 0;
}
return DefMDIChildProc(hWnd, message, wParam, lParam); }
/*
* */ VOID MDICreate( HWND hWnd, LONG lParam ) { RECT rect; DWORD xList; DWORD yList; DWORD cxList; DWORD cyList; PMDIWIN_INFO pMDIWinInfo; RECT rectHeader; INT i, ColumnWidths[MAX_HEADERS]; HD_ITEM hdi; RECT rcParent; HD_LAYOUT hdl; WINDOWPOS wp;
DBGMSG( DBG_TRACE, ( "Enter MDICreate %08x\n", hWnd ) );
// The first time thru we have to pickup the pQueue value from
// the extra Params field of the CREATESTRUCT
pMDIWinInfo = (PMDIWIN_INFO)(((LPMDICREATESTRUCT) (((LPCREATESTRUCT)lParam)->lpCreateParams))->lParam);
/* Store the MDIWIN_INFO struct pointer in the window struct for
* future use during other message processing by the WinProc. */ SetWindowLong(hWnd, GWL_PMDIWIN, (unsigned)pMDIWinInfo);
pMDIWinInfo->hwnd = hWnd; pMDIWinInfo->Alive = TRUE; CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)RefreshThread, pMDIWinInfo, 0, &pMDIWinInfo->ThreadId );
pMDIWinInfo->hwndHeader = CreateWindow (WC_HEADER, TEXT(""), WS_CHILD | WS_BORDER | CCS_TOP, 0,0,0,0, hWnd, (HMENU) ID_HEADER, hInst, NULL);
GetClientRect(hWnd, &rcParent);
hdl.prc = &rcParent; hdl.pwpos = ℘
SendMessage(pMDIWinInfo->hwndHeader, HDM_LAYOUT, 0, (LPARAM)&hdl);
if (!bJapan) { SendMessage( pMDIWinInfo->hwndHeader, WM_SETFONT, (WPARAM)hfontHelvBold, 1L ); }
for( i = 0; i < pMDIWinInfo->cColumns; i++ ) { ColumnWidths[i] = pMDIWinInfo->pColumns[i].Width; }
if( ColumnWidths[0] == CW_USEDEFAULT ) SetDefaultColumnWidths( hWnd, pMDIWinInfo, ColumnWidths );
hdi.mask = HDI_TEXT | HDI_FORMAT | HDI_WIDTH; hdi.fmt = HDF_LEFT | HDF_STRING;
for( i = 0; i < pMDIWinInfo->cColumns; i++ ) {
hdi.pszText = pMDIWinInfo->pColumns[i].Text; hdi.cxy = ColumnWidths[i]; hdi.cchTextMax = lstrlen(hdi.pszText);
SendMessage(pMDIWinInfo->hwndHeader, HDM_INSERTITEM, (WPARAM) pMDIWinInfo->cColumns+ 1, (LPARAM)&hdi); }
SetWindowPos(pMDIWinInfo->hwndHeader, wp.hwndInsertAfter, wp.x, wp.y, wp.cx, wp.cy, wp.flags | SWP_SHOWWINDOW);
/* Calculate width and height of the list box:
*/ GetWindowRect( pMDIWinInfo->hwndHeader, &rectHeader ); HeaderHeight = (rectHeader.bottom - rectHeader.top);
GetWindowRect(hWnd, &rect); xList = 0; yList = HeaderHeight; cxList = rect.right; cyList = rect.bottom - HeaderHeight;
yList = rectHeader.bottom; cyList = rect.bottom - rectHeader.bottom;
/* Create Queue and Job Status list box control in client window
*/ pMDIWinInfo->hwndList = CreateWindow( TEXT("LISTBOX"), NULL, WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_CLIPSIBLINGS | LBS_NOTIFY | LBS_OWNERDRAWFIXED | LBS_NODATA | LBS_NOINTEGRALHEIGHT | LBS_WANTKEYBOARDINPUT, xList, yList, cxList, cyList, hWnd, (HMENU)ID_OBJLIST, hInst, NULL);
// CountryCode - krishnag
// #ifndef JAPAN
if (!bJapan) { SendMessage( pMDIWinInfo->hwndList, WM_SETFONT, (WPARAM)hfontHelv, 1L ); } // #endif
// SendMessage( pMDIWinInfo->hwndList, LB_SETCOUNT, *pMDIWinInfo->pcObjects, 0L );
if( pMDIWinInfo->WindowType != MDIWIN_SERVER ) { MakeDragList( pMDIWinInfo->hwndList );
if( !WM_DragList ) WM_DragList = RegisterWindowMessage( DRAGLISTMSGSTRING );
DefListboxWndProc = (WNDPROC)SetWindowLong( pMDIWinInfo->hwndList, GWL_WNDPROC, (LONG)SubclassListboxWndProc ); pMDIWinInfo->ObjSelected = NOSELECTION; pMDIWinInfo->DragPosition = NOSELECTION; } else { SendMessage( pMDIWinInfo->hwndList, LB_SETCURSEL, 0, 0L ); pMDIWinInfo->ObjSelected = 0; pMDIWinInfo->DragPosition = NOSELECTION; *pMDIWinInfo->ppSelData = *pMDIWinInfo->ppData; }
DBGMSG( DBG_TRACE, ( "Exit MDICreate %08x\n", hWnd ) ); }
/*
* */ VOID SetDefaultColumnWidths( HWND hwnd, PMDIWIN_INFO pMDIWinInfo, PINT pColumnWidths ) { RECT rect; PCOLUMN pDefaultColumn; INT i; INT TotalWidth; INT AvailableWidth;
GetWindowRect( hwnd, &rect ); AvailableWidth = ( rect.right - rect.left );
if( pMDIWinInfo->WindowType == MDIWIN_SERVER ) pDefaultColumn = MDIServerDefaultColumn; else pDefaultColumn = MDIPrinterDefaultColumn;
for( i = 0, TotalWidth = 0; i < pMDIWinInfo->cColumns; i++ ) TotalWidth += pDefaultColumn[i].Width;
/* Size the headers so that they use up the space available.
*/ for( i = 0; i < pMDIWinInfo->cColumns; i++ ) pColumnWidths[i] = pMDIWinInfo->pColumns[i].Width = ( pDefaultColumn[i].Width * AvailableWidth / TotalWidth ); }
/* MDIPaint
* * Called in response to the WM_PAINT message. * * If the window is iconic, and we're going to draw our own icon, do it. * * If it isn't iconic, draw the status bar. */ LONG MDIPaint(HWND hwnd, WPARAM wParam, LPARAM lParam) { PMDIWIN_INFO pMDIWinInfo; HDC hdc; PAINTSTRUCT ps; LONG rc;
pMDIWinInfo = GETMDIWIN( hwnd );
hdc = BeginPaint(hwnd, &ps);
if (IsIconic(hwnd)) { if( pMDIWinInfo->hicon ) DrawIcon( hdc, 0, 0, pMDIWinInfo->hicon );
EndPaint(hwnd, &ps); } else { EndPaint(hwnd, &ps);
rc = DefMDIChildProc(hwnd, WM_PAINT, wParam, lParam);
/* Do the default stuff, which should cause an initial paint,
* then fake a timer message to ensure the window is up to date. * This may result in the window being painted twice, but at least * there won't be an obvious delay while the job info gets refreshed. */ }
return rc; }
/* MDIEraseBkgnd
* * We're interested in the WM_ERASEBKGND message if we're drawing our own icon. * * Return: * * TRUE if the background was successfully painted. * Otherwise, the message should be passed to the default procedure. * */ BOOL MDIEraseBkgnd(HWND hwnd, HDC hdc) { PMDIWIN_INFO pMDIWinInfo; HBRUSH hbrush; RECT rect; BOOL Painted = FALSE;
pMDIWinInfo = GETMDIWIN( hwnd );
if( IsIconic( hwnd ) && pMDIWinInfo->hicon ) { hbrush = CreateSolidBrush( GetSysColor( COLOR_APPWORKSPACE ) );
GetWindowRect( hwnd, &rect );
/* rect is in screen coordinates.
* We must convert to client coordinates: */ ScreenToClient( hwnd, &((LPPOINT)&rect)[0] ); ScreenToClient( hwnd, &((LPPOINT)&rect)[1] );
Painted = FillRect( hdc, &rect, hbrush );
DeleteObject( hbrush ); }
return Painted; }
/* MDIQueryDragIcon
* * Called if the user is dragging an icon around. * Just returns the icon handle for the window, which is non-null for * icons that we draw ourselves. */ HICON MDIQueryDragIcon(HWND hwnd) { PMDIWIN_INFO pMDIWinInfo;
pMDIWinInfo = GETMDIWIN( hwnd );
return pMDIWinInfo->hicon; }
/* Respond to system menu selections in MDI windows.
* Update the status bar correspondingly. */ LONG MDIMenuSelect( HWND hwnd, WPARAM wParam, LPARAM lParam ) { UINT ItemID; UINT Flags;
ItemID = (UINT)LOWORD( wParam ); Flags = (UINT)HIWORD( wParam );
MenuHelp( WM_MENUSELECT, wParam, lParam, GetMenu( hwnd ), hInst, hwndStatus, pMenuHelpIDs);
if( ItemID && ( Flags & MF_SYSMENU ) ) WinHelpMenuID = ID_HELP_MDI_SYSMENU; else WinHelpMenuID = ItemID;
return 0; }
/* MDICommandObjListSelChange
* * This routine will be called when a new selection is made in the list. * It will also be called if the user just clicks on an already selected * list item. * * If the user is clicking, we want to toggle selection of this item, * otherwise reflect the change of selection in our instance data. * * If the user's been dragging a job in a printer window, and has now * released the mouse back where it started, don't toggle. * * */ VOID MDICommandObjListSelChange( HWND hwnd ) { PMDIWIN_INFO pInfo; DWORD Selection;
if( !(pInfo = GETMDIWIN(hwnd) ) ) return;
Selection = (DWORD)GETLISTSELECT( hwnd, ID_OBJLIST );
ENTER_PROTECTED_DATA( pInfo );
if( ( Selection == pInfo->ObjSelected ) &&( pInfo->WindowType != MDIWIN_SERVER ) &&( pInfo->DragPosition == NOSELECTION ) ) { Selection = NOSELECTION; SETLISTSELECT( hwnd, ID_OBJLIST, Selection ); }
/* Beware, jobs may have gone away since USER sent us the message;
* ensure that the data is still valid: */ else if( !*pInfo->ppData ) { Selection = NOSELECTION; SETLISTSELECT( hwnd, ID_OBJLIST, Selection ); }
SetObjectSelection( pInfo, Selection );
EnableCheckTBButtons(hwnd); UpdateStatus(hwnd);
LEAVE_PROTECTED_DATA( pInfo ); }
/* Set Print Manager's internal data structures to correspond to the selection:
* */ VOID SetObjectSelection( PMDIWIN_INFO pInfo, DWORD Selection ) { DBG_IN_PROTECTED_DATA( pInfo );
if( Selection == NOSELECTION ) { *pInfo->ppSelData = NULL; *pInfo->pSelObjId = 0; } else { *pInfo->ppSelData = (PBYTE)( *pInfo->ppData + ( ( Selection - *pInfo->pFirstEnumObj ) * pInfo->DataSize ) );
*pInfo->pSelObjId = *(DWORD *)( *pInfo->ppSelData + pInfo->IdOffset ); }
pInfo->ObjSelected = Selection; }
/*
* */ VOID MDICommandObjListDblClk( HWND hwnd ) { PMDIWIN_INFO pMDIWinInfo; PSERVER_CONTEXT pServerContext; PQUEUE pQueue; PPRINTER_INFO_2 pPrinterSelected; HWND hwndPrinter;
pMDIWinInfo = (PMDIWIN_INFO)GetWindowLong(hwnd, GWL_PMDIWIN);
if( pMDIWinInfo->WindowType != MDIWIN_SERVER ) { ENTER_PROTECTED_DATA( pMDIWinInfo );
pQueue = (PQUEUE)pMDIWinInfo->pContext;
if (pQueue->pSelJob) DialogBoxParam (hInst, MAKEINTRESOURCE(DLG_DOCTAILS), hwnd, (DLGPROC)DocDetailsDlg, (DWORD)pQueue);
LEAVE_PROTECTED_DATA( pMDIWinInfo ); }
else { WCHAR szPrinterName[MAX_PATH]; DWORD dwStatus;
/* This is a Server Viewer:
*/ pServerContext = pMDIWinInfo->pContext;
ENTER_PROTECTED_DATA( pMDIWinInfo );
/* See if there's already an MDI window for the printer name
* we just clicked on: * * !!! Actually we will probably have to combine it with the * !!! server name. */ pPrinterSelected = pServerContext->pSelPrinter;
if (pPrinterSelected && pPrinterSelected->pPrinterName) {
wcscpy(szPrinterName, pPrinterSelected->pPrinterName); dwStatus = pPrinterSelected->Status;
} else {
LEAVE_PROTECTED_DATA( pMDIWinInfo ); return; }
LEAVE_PROTECTED_DATA( pMDIWinInfo );
hwndPrinter = FindPrinterWindow( szPrinterName );
/* If so, just bring it into focus:
*/ if( hwndPrinter ) { SendMessage( hwndClient, WM_MDIACTIVATE, (WPARAM)hwndPrinter, 0L );
if( IsIconic( hwndPrinter ) ) ShowWindow( hwndPrinter, SW_RESTORE ); }
/* Otherwise create a new MDI window for this printer:
*/ else { SetCursor( hcursorWait );
if( AddPrinterConnection( szPrinterName ) ) { if( pQueue = AllocQueue( szPrinterName ) ) { pQueue->Error = OpenThreadObject(pQueue->pPrinterName, &pQueue->hPrinter, &pQueue->AccessGranted, MDIWIN_PRINTER); if( !pQueue->Error ) { pQueue->pServerName = AllocSplStr( pServerContext->pServerName );
CreateQueueWindow( hwnd, pQueue, dwStatus, MDIWIN_NETWORKPRINTER, FALSE ); UpdateDefaultList(); } else { FreeQueue( pQueue );
ReportFailure( hwnd, 0, IDS_COULDNOTOPENPRINTER ); } } } else { if( GetLastError( ) == ERROR_UNKNOWN_PRINTER_DRIVER ) Message( hwnd, MSG_ERROR, IDS_PRINTMANAGER, IDS_NO_DRIVER_ON_SERVER ); else ReportFailure( hwnd, 0, IDS_COULDNOTCONNECTTOPRINTER ); }
SetCursor( hcursorArrow ); } } }
/* MDICommandHeaderBeginDrag
* * Called when the user begins to drag a movable column in an MDI list. * Queries the current position and marks the appropriate rectangle. * * Parameters: * * hwnd - The handle of the MDI window. * * pCursorPos - A pointer to the coordinates of the cursor. * Initially undefined, it will be updated with the new coordinates. * */ VOID MDICommandHeaderBeginDrag( HWND hwnd, PPOINT pCursorPos ) { PMDIWIN_INFO pMDIWinInfo;
pMDIWinInfo = (PMDIWIN_INFO)GetWindowLong(hwnd, GWL_PMDIWIN);
/* Don't permit the window to be refreshed while we're dragging:
*/ ENTER_PROTECTED_DATA( pMDIWinInfo ); ResetEvent( pMDIWinInfo->RefreshSignal ); LEAVE_PROTECTED_DATA( pMDIWinInfo );
if( GetCursorPos( pCursorPos ) ) { ScreenToClient( hwnd, pCursorPos ); InvertDragMark( hwnd, pCursorPos ); } }
/* MDICommandHeaderDragging
* * Called when the user is dragging a movable column in an MDI list. * Calls InvertDragMark to clear the previous mark, then updates the current * position and inverts the new mark area. * * Parameters: * * hwnd - The handle of the MDI window. * * pCursorPos - A pointer to the previous coordinates of the cursor. * This will be updated with the new coordinates. * */ VOID MDICommandHeaderDragging( HWND hwnd, PPOINT pCursorPos, HD_NOTIFY * lpNot ) { InvertDragMark( hwnd, pCursorPos );
#ifdef DRAG_AS_WE_GO
/* This doesn't look too wonderful, cos there's a lot to do to keep up:
*/ UpdateColumns( hwnd, lpNot ); #endif /* DRAG_AS_WE_GO */
if( GetCursorPos( pCursorPos ) ) { ScreenToClient( hwnd, pCursorPos ); InvertDragMark( hwnd, pCursorPos ); } }
/* MDICommandHeaderEndDrag
* * Called when the user releases the mouse button after dragging a movable * column heading. * * Parameters: * * hwnd - The handle of the MDI window. * * pCursorPos - A pointer to the current coordinates of the cursor. * * */ VOID MDICommandHeaderEndDrag( HWND hwnd, PPOINT pCursorPos, HD_NOTIFY * lpNot ) { PMDIWIN_INFO pMDIWinInfo;
pMDIWinInfo = GETMDIWIN(hwnd);
InvertDragMark( hwnd, pCursorPos );
UpdateColumns( hwnd, lpNot );
ENTER_PROTECTED_DATA( pMDIWinInfo ); SetEvent( pMDIWinInfo->RefreshSignal ); LEAVE_PROTECTED_DATA( pMDIWinInfo ); }
/* InvertDragMark
* * Puts up a vertical mark to indicate where the user is dragging the movable * headers of a list box. * This function is called both to set and to clear the mark, since it simply * inverts the mark rectangle. * * Parameters: * * hwnd - The handle of the MDI window. * * pCursorPos - A pointer to the current coordinates of the cursor. * */ #define MARKERWIDTH 2
VOID InvertDragMark( HWND hwnd, PPOINT pCursorPos ) { PMDIWIN_INFO pMDIWinInfo; HWND hwndList; RECT rcMark; HDC hdc;
pMDIWinInfo = GETMDIWIN( hwnd );
hwndList = pMDIWinInfo->hwndList;
if( GetClientRect( hwnd, &rcMark ) ) { rcMark.left = pCursorPos->x; rcMark.right = ( rcMark.left + MARKERWIDTH );
hdc = GetDC( hwndList );
InvertRect( hdc, &rcMark );
ReleaseDC( hwndList, hdc ); } }
/* UpdateColumns
* * Finds out the new widths of the columns by sending * HDM_GETITEM to the movable header control. Then updates the heading * parameters in the window's instance data, and causes the list to repaint. * * Parameter: * * hwnd - The handle of the MDI window. * */ VOID UpdateColumns( HWND hwnd, HD_NOTIFY * lpNot ) { PMDIWIN_INFO pMDIWinInfo; INT i, HeaderWidth[MAX_HEADERS]; INT cColumns; PCOLUMN pColumn; HD_ITEM hdi;
pMDIWinInfo = GETMDIWIN(hwnd);
cColumns = SendMessage( pMDIWinInfo->hwndHeader, HDM_GETITEMCOUNT,0,0);
pColumn = GETCOLUMN( hwnd );
hdi.mask = HDI_WIDTH;
for( i = 0; i < cColumns; i++ ) { if (i != lpNot->iItem) { Header_GetItem(pMDIWinInfo->hwndHeader, i, &hdi); } else { hdi.cxy = lpNot->pitem->cxy; } pColumn[i].Width = hdi.cxy; }
InvalidateRect( pMDIWinInfo->hwndList, NULL, FALSE ); }
/* If someone's dropped a file on one of the MDI printer windows,
* we must ensure that the printer is default, since apps like File Manager * just print to the default printer. * Unfortunately, we can't revert to the previous default printer, because * we won't know when the job has completed printing. */ VOID MDIDropObject( HWND hwnd ) { PMDIWIN_INFO pInfo;
pInfo = GETMDIWIN(hwnd);
/* This should never be false:
*/ if( pInfo->WindowType != MDIWIN_SERVER ) { /* Set the default printer and update the default combo */
} }
/* Verify that we can close this MDI window with the system menu Close option.
* If not, an SC_MINIMIZE code should be sent to the window. */ BOOL MDIClose( HWND hwnd ) { PMDIWIN_INFO pInfo;
pInfo = GETMDIWIN(hwnd);
if( !pInfo ) return FALSE;
/* We can close only server windows:
*/ if( pInfo->WindowType == MDIWIN_SERVER ) { /* Just in case this is the last MDI window, clear the
* toolbar buttons and status bar: */ EnableCheckTBButtons(NULL); UpdateStatus(NULL);
return TRUE; }
else return FALSE; }
/* MDIVKeyToItemSpace
* * Respond to spacebar presses by toggling document selection in printer * windows. * */ VOID MDIVKeyToItemSpace( HWND hwnd ) { PMDIWIN_INFO pInfo; DWORD Selection; DWORD TopIndex; RECT rcDragPosition;
pInfo = GETMDIWIN(hwnd);
if( !pInfo ) return;
if( pInfo->WindowType != MDIWIN_SERVER ) { ENTER_PROTECTED_DATA( pInfo );
Selection = (DWORD)GETLISTSELECT( hwnd, ID_OBJLIST );
/* If there is no selection, retrieve the last selected guy,
* if it's in range: */ if( Selection == LB_ERR ) { TopIndex = SendMessage( pInfo->hwndList, LB_GETTOPINDEX, 0, 0L ); if( ( pInfo->PrevSelection >= TopIndex ) &&( pInfo->PrevSelection <= ( TopIndex + pInfo->cNumLines ) ) ) pInfo->ObjSelected = pInfo->PrevSelection; else pInfo->ObjSelected = TopIndex;
/* Let's err on the side of caution;
* ensure that the data is still valid: */ if( !*pInfo->ppData ) { Selection = NOSELECTION; SETLISTSELECT( hwnd, ID_OBJLIST, Selection ); }
SetObjectSelection( pInfo, pInfo->ObjSelected );
pInfo->PrevSelection = 0; } else { pInfo->PrevSelection = Selection; pInfo->ObjSelected = NOSELECTION; pInfo->DragPosition = NOSELECTION; *pInfo->pSelObjId = 0; }
SETLISTSELECT( hwnd, ID_OBJLIST, pInfo->ObjSelected );
if( pInfo->DragPosition != NOSELECTION ) { pInfo->DragPosition = NOSELECTION;
SendMessage( pInfo->hwndList, LB_GETITEMRECT, pInfo->DragPosition, (LPARAM)&rcDragPosition ); InvalidateRect( pInfo->hwndList, &rcDragPosition, FALSE ); }
EnableCheckTBButtons(hwnd); UpdateStatus(hwnd);
LEAVE_PROTECTED_DATA( pInfo ); } }
/*
* */ VOID MDIParentNotifyRButtonDown( HWND hwnd, DWORD CursorPos ) { PMDIWIN_INFO pInfo; POINT ptCursor; INT LBItem;
pInfo = GETMDIWIN(hwnd); if( !pInfo ) return;
if( ( pInfo->WindowType != MDIWIN_SERVER ) &&( pInfo->DragPosition == NOSELECTION ) ) { LONG2POINT( CursorPos, ptCursor ); ClientToScreen( hwnd, &ptCursor );
LBItem = LBItemFromPt( pInfo->hwndList, ptCursor, FALSE );
if( LBItem == (INT)pInfo->ObjSelected ) { SETLISTSELECT( hwnd, ID_OBJLIST, NOSELECTION ); SendMessage( hwnd, WM_COMMAND, GET_WM_COMMAND_MPS( GetDlgCtrlID( pInfo->hwndList ), pInfo->hwndList, LBN_SELCHANGE ) ); } } }
/*
* */ VOID MDIVKeyToItemDefault( HWND hwnd ) { PMDIWIN_INFO pInfo;
pInfo = GETMDIWIN(hwnd); if( !pInfo ) return;
SendMessage( pInfo->hwndList, WM_RBUTTONDOWN, 0, 0L );
/* Clear any previous reorder mark:
*/ ClearDragPosition( pInfo ); }
/* ReorderJob
* * Sets the job position to the value in the DragPosition field of pInfo, * then forces a refresh of the job buffer. * */ VOID ReorderJob( HWND hwnd, PMDIWIN_INFO pInfo, DWORD Position ) { PQUEUE pQueue; LPJOB_INFO_2 pJobReorder;
pQueue = (PQUEUE)pInfo->pContext;
if( !pQueue || !pQueue->pJobs ) return;
if( ( pInfo->ObjSelected == NOSELECTION ) || ( Position == NOSELECTION ) ) return;
ENTER_PROTECTED_DATA( pInfo );
pJobReorder = pQueue->pSelJob;
if( ( pJobReorder == NULL ) || ( pJobReorder == (LPJOB_INFO_2)NOSELECTION ) ) { DBGMSG( DBG_ERROR, ( "Error: ReorderJob called with pSelJob == %d", pJobReorder ) );
LEAVE_PROTECTED_DATA( pInfo );
return; }
DBGMSG( DBG_INFO, ( "ReorderJob: JobId = %d; Position = %d\n", pJobReorder->JobId, pJobReorder->Position ) );
if( pJobReorder ) { BOOL OK;
/* Spooler order is 1-based:
*/ pJobReorder->Position = ( Position + 1 );
OK = SetJob( pQueue->hPrinter, pJobReorder->JobId, 2, (LPBYTE)pJobReorder, 0 );
if( !OK ) ReportFailure( hwnd, 0, IDS_COULD_NOT_REORDER_JOB ); }
LEAVE_PROTECTED_DATA( pInfo ); }
/*
* */ VOID MarkPosition( PMDIWIN_INFO pInfo, DWORD Position ) { DWORD OldPosition;
/* N.B. Ensure pInfo->DragPosition is updated before we do any repainting,
* since MDIDrawItem depends on it: */
if( pInfo->DragPosition != Position ) { /* If the top index hasn't been reset, we need to force a repaint
* of the old and new reorder positions: */ OldPosition = pInfo->DragPosition; pInfo->DragPosition = Position; RepaintListboxItem( pInfo->hwndList, OldPosition );
if( Position != (DWORD) NOSELECTION ) RepaintListboxItem( pInfo->hwndList, Position ); } }
/* MDIVKeyToItemUpDown
* * Called when the user presses an up or down cursor. * We're interested in this only if the control key is also depressed * at the same time, otherwise we rely on the default system response. * * The Ctrl-Up or Ctrl-Down combination is used * */ int MDIVKeyToItemUpDown( HWND hwnd, WORD VKey ) { PMDIWIN_INFO pInfo; DWORD Selection; DWORD TopIndex; DWORD DragPosition;
pInfo = GETMDIWIN(hwnd);
/* if the high-order bit of the SHORT returned from GetKeyState
* is on, the key is down: */ if( ( pInfo->WindowType != MDIWIN_SERVER ) &&( GetKeyState( VK_CONTROL ) & 0x8000 ) &&( pInfo->pContext ) &&( ( (PQUEUE)( pInfo->pContext ) )->AccessGranted & PRINTER_ACCESS_ADMINISTER ) ) { ENTER_PROTECTED_DATA( pInfo ); ResetEvent( pInfo->RefreshSignal ); LEAVE_PROTECTED_DATA( pInfo );
Selection = (DWORD)GETLISTSELECT( hwnd, ID_OBJLIST ); TopIndex = SendMessage( pInfo->hwndList, LB_GETTOPINDEX, 0, 0L );
DragPosition = pInfo->DragPosition;
if( DragPosition == NOSELECTION ) { DragPosition = Selection; pInfo->ObjSelected = Selection; }
switch( VKey ) { case VK_UP: case VK_LEFT: if( DragPosition > 0 ) DragPosition--; break; case VK_DOWN: case VK_RIGHT: if( DragPosition < ( *pInfo->pcObjects - 1 ) ) DragPosition++; }
/* N.B. Ensure pInfo->DragPosition is updated before we do any repainting,
* since MDIDrawItem depends on it: */
if( pInfo->DragPosition != DragPosition ) { MarkPosition( pInfo, DragPosition );
/* Scroll up a line if we've gone off the top:
*/ if( DragPosition < TopIndex ) SendMessage( pInfo->hwndList, LB_SETTOPINDEX, DragPosition, 0L ); /* Scroll down a line if we've gone off the bottom:
*/ else if( DragPosition >= ( TopIndex + pInfo->cNumLines ) ) SendMessage( pInfo->hwndList, LB_SETTOPINDEX, TopIndex+1, 0L ); }
LEAVE_PROTECTED_DATA( pInfo );
return -2; }
else { if( pInfo->DragPosition != NOSELECTION ) { pInfo->DragPosition = NOSELECTION;
RepaintListboxItem( pInfo->hwndList, pInfo->DragPosition ); }
return -1; } }
/*
* */ VOID RepaintListboxItem( HWND hwndListbox, DWORD ItemID ) { RECT rcItem;
SendMessage( hwndListbox, LB_GETITEMRECT, ItemID, (LPARAM)&rcItem ); InvalidateRect( hwndListbox, &rcItem, FALSE ); }
/* Size the list in sync with the MDI window
* */ VOID MDISize( HWND hWnd, DWORD Coordinates ) { PMDIWIN_INFO pMDIWinInfo; DWORD cxList, cyList;
pMDIWinInfo = GETMDIWIN(hWnd);
cxList = LOWORD(Coordinates); cyList = HIWORD(Coordinates) - HeaderHeight;
SetWindowPos (pMDIWinInfo->hwndHeader, 0, 0, 0, cxList, HeaderHeight, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
/* Count partial lines in the list box:
*/ pMDIWinInfo->cNumLines = ( cyList / STATUS_BITMAP_HEIGHT );
// Move listbox child window also
MoveWindow(pMDIWinInfo->hwndList, 0, HeaderHeight, cxList, cyList, TRUE); }
/*
* */ LONG MDIMDIActivate( HWND hwnd, HWND hwndDeactivate, HWND hwndActivate ) { PMDIWIN_INFO pMDIWinInfo; DWORD CurSel; DWORD TopIndex;
if( hwnd == hwndActivate ) { pMDIWinInfo = GETMDIWIN(hwnd);
ENTER_PROTECTED_DATA( pMDIWinInfo );
if( pMDIWinInfo ) { CurSel = SendMessage( pMDIWinInfo->hwndList, LB_GETCURSEL, 0, 0L ); TopIndex = SendMessage( pMDIWinInfo->hwndList, LB_GETTOPINDEX, 0, 0L );
if( ( TopIndex <= CurSel ) && ( CurSel < pMDIWinInfo->cNumLines ) ) SendMessage( pMDIWinInfo->hwndList, LB_SETCURSEL, CurSel, 0L ); }
EnableCheckTBButtons(hwnd); UpdateStatus(hwnd);
LEAVE_PROTECTED_DATA( pMDIWinInfo ); } else if (hwnd == hwndDeactivate){ pMDIWinInfo = GETMDIWIN(hwnd); if (pMDIWinInfo) { CurSel = SendMessage( pMDIWinInfo->hwndList, LB_GETCURSEL, 0, 0L); SendMessage(pMDIWinInfo->hwndList, LB_SETCURSEL, CurSel, -1);
} } return 0; }
/* MDINCActivate
* * Forget about any drag operations that have been started * if we're going inactive */ VOID MDINCActivate( HWND hwnd ) { PMDIWIN_INFO pInfo;
pInfo = GETMDIWIN(hwnd);
if( !pInfo || ( pInfo->WindowType == MDIWIN_SERVER ) ) return;
SendMessage( pInfo->hwndList, WM_RBUTTONDOWN, 0, 0L );
/* Clear any previous reorder mark:
*/ ClearDragPosition( pInfo ); }
/*
* */ LONG MDIWindowPosChanged( HWND hwnd, WPARAM wParam, LPARAM lParam ) { HWND hwndActive; PMDIWIN_INFO pInfo; LONG rc; PWINDOWPOS pWindowPos = (PWINDOWPOS)lParam;
rc = DefMDIChildProc(hwnd, WM_WINDOWPOSCHANGED, wParam, lParam);
if( !( pWindowPos->flags & SWP_HIDEWINDOW ) &&( hwndActive = (HWND)SendMessage(hwndClient, WM_MDIGETACTIVE, 0, 0L))) { if( pInfo = GETMDIWIN(hwndActive) ) { ENTER_PROTECTED_DATA(pInfo);
UpdateStatus(hwndActive);
LEAVE_PROTECTED_DATA(pInfo); } }
return rc; }
/*
* */ VOID ClearDragPosition( PMDIWIN_INFO pInfo ) { DWORD OldDragPosition;
if( ( OldDragPosition = pInfo->DragPosition ) != NOSELECTION ) { pInfo->DragPosition = NOSELECTION; RepaintListboxItem( pInfo->hwndList, OldDragPosition ); ENTER_PROTECTED_DATA( pInfo ); SetEvent( pInfo->RefreshSignal ); LEAVE_PROTECTED_DATA( pInfo ); } }
/*
* */ VOID MDISetFocus( HWND hwnd ) { PMDIWIN_INFO pMDIWinInfo;
pMDIWinInfo = GETMDIWIN(hwnd);
/* Ensure that keyboard input will be sent to the listbox:
*/ SetFocus( pMDIWinInfo->hwndList ); }
/*
* */ VOID MDIMeasureItem( HWND hwnd, LPMEASUREITEMSTRUCT pmis ) {
/* For now just specify the bitmap size.
* This will have to change if font selection becomes a reality: */ pmis->itemHeight = STATUS_BITMAP_HEIGHT; }
#define LEFTMARGIN 2
#define MAXCOLUMNWIDTH 256
/*
* */ VOID MDIDrawItem( HWND hwnd, LPDRAWITEMSTRUCT pdis ) { PMDIWIN_INFO pInfo; RECT WindowRect, LineRect; PCOLUMN pColumn; TCHAR string[MAXCOLUMNWIDTH]; int i; int j; PBYTE pData; BOOL ThisWindowIsActive; BOOL Selected; DWORD ColumnLeft;
pInfo = GETMDIWIN(hwnd);
if( !pInfo ) return;
if( pdis->itemID == (UINT)-1 ) { DrawFocusRect( pdis->hDC, &pdis->rcItem ); return; }
if( pdis->itemID == 0 ) pInfo->TopIndex = SendMessage( pdis->hwndItem, LB_GETTOPINDEX, 0, 0 );
ENTER_PROTECTED_DATA( pInfo );
GetWindowRect( hwnd, &WindowRect );
pColumn = pInfo->pColumns;
i = ( (int)pdis->itemID - (int)*pInfo->pFirstEnumObj );
/* If we've strayed outside our buffer of jobs, refresh the jobs list:
*/ if( ( i < 0 ) || ( (DWORD)i >= *pInfo->pcEnumObjs ) ) { DBGMSG( DBG_TRACE, ( "MDIDrawItem calling GetJobs\n" ) );
/* This should always be true, since we're enumerating
* all the printers in a Server window: */ if( pInfo->WindowType != MDIWIN_SERVER ) { DWORD TopIndex; DWORD dwChangeJob;
TopIndex = SendMessage( pInfo->hwndList, LB_GETTOPINDEX, 0, 0L );
/* Enumerate a buffer big enough to page up once ...
*/ *pInfo->pFirstEnumObj = (DWORD)max( 0, (int)TopIndex - (int)pInfo->cNumLines );
SetCursor( hcursorWait ); ENTER_PROTECTED_DATA( pInfo );
dwChangeJob = PRINTER_CHANGE_JOB; GetJobs( pInfo->pContext, &dwChangeJob );
LEAVE_PROTECTED_DATA( pInfo ); SetCursor( hcursorArrow ); }
i = ( (int)pdis->itemID - (int)*pInfo->pFirstEnumObj );
/* HARMLESS HACK:
* * If there's a lot of scrolling going on at the moment, * it sometimes still isn't in sync with the buffer, * so bomb out to avoid attempting to reference a job * we haven't got: */ if( ( i < 0 ) || ( (DWORD)i >= *pInfo->pcEnumObjs ) ) { LEAVE_PROTECTED_DATA( pInfo ); return; } }
/* Maybe there was some sort of error last time we enumerated.
* If so, ppData should be NULL. Bomb out: */ if( !*pInfo->ppData ) { LEAVE_PROTECTED_DATA( pInfo ); return; }
pData = ( *pInfo->ppData + ( (DWORD)i * pInfo->DataSize ) );
/* See comment on CreateWindowInfo - we need to
determine whether printer status information is being generated by the Status field in JOB_INFO_2 or the pStatus field in JOB_INFO_2. Also check to see that the pInfo window type is not MDIWIN_SERVER */ if (pInfo->WindowType != MDIWIN_SERVER) { if (((PJOB_INFO_2)pData)->pStatus != NULL) { pInfo->pColumns[MDIHEAD_JOB_STATUS].Offset = offsetof(JOB_INFO_2, pStatus); pInfo->pColumns[MDIHEAD_JOB_STATUS].Datatype = MDIDATA_PSZ; } else { pInfo->pColumns[MDIHEAD_JOB_STATUS].Offset = offsetof(JOB_INFO_2, Status); pInfo->pColumns[MDIHEAD_JOB_STATUS].Datatype = MDIDATA_JOB_STATUS; } }
LineRect = pdis->rcItem;
ThisWindowIsActive = ( hwnd == (HWND)SendMessage(hwndClient, WM_MDIGETACTIVE, 0, 0L) );
Selected = ( ThisWindowIsActive && ( pdis->itemState & ODS_SELECTED ) );
/* Special case the status icon and first column:
*/ DisplayStatusIcon( pdis->hDC, &LineRect, pInfo->WindowType, ( pData + pInfo->IconStatus ), Selected );
/* Pad some blanks at the left of the field:
*/ for( i = 0; i < LEFTMARGIN; i++ ) string[i] = SPACE;
ColumnLeft = 0;
for( j = 0; j < pInfo->cColumns; j++ ) { FormatData( ( pData + pColumn[j].Offset ), pColumn[j].Datatype, &string[LEFTMARGIN-1] );
LineRect.left = ColumnLeft; if( j == 0 ) LineRect.left += STATUS_BITMAP_SPACE;
LineRect.right = ( ColumnLeft + pColumn[j].Width );
DrawLine( pdis->hDC, &LineRect, string, Selected );
/* If this is the last column and this is a highlight line,
* continue the highlight to the right-hand side of the window: */ if( j == ( pInfo->cColumns - 1 ) ) { LineRect.left = LineRect.right; LineRect.right = WindowRect.right; DrawLine( pdis->hDC, &LineRect, TEXT(""), Selected ); }
ColumnLeft += pColumn[j].Width; }
if( pdis->itemState & ODS_FOCUS ) DrawFocusRect( pdis->hDC, &pdis->rcItem );
if( ( pInfo->WindowType != MDIWIN_SERVER ) &&( pdis->itemID == pInfo->DragPosition ) ) { HBRUSH hbr;
if( hbr = CreateSolidBrush( GetSysColor( COLOR_HIGHLIGHT ) ) ) { LineRect = pdis->rcItem;
if( pInfo->DragPosition > pInfo->ObjSelected ) LineRect.top = LineRect.bottom-1; else LineRect.bottom = LineRect.top+1;
FrameRect( pdis->hDC, &LineRect, hbr ); DeleteObject( hbr ); } }
LEAVE_PROTECTED_DATA( pInfo ); }
/*
* */ VOID MDITimer( HWND hWnd ) { PMDIWIN_INFO pInfo; BOOL CheckStatus; DWORD OldStatus; DWORD NewStatus; PQUEUE pQueue; BOOL PrinterNameChanged = FALSE;
pInfo = GETMDIWIN( hWnd );
if( !pInfo ) return;
/* If the status of a printer has changed to/from Paused,
* we want to update the title (even if it's iconic). * This may have happened even though the MDI window * isn't active (e.g. through the Server Viewer). */ CheckStatus = ( pInfo->WindowType != MDIWIN_SERVER );
ENTER_PROTECTED_DATA( pInfo );
if( CheckStatus ) { pQueue = (PQUEUE)pInfo->pContext;
if( !pQueue ) { LEAVE_PROTECTED_DATA( pInfo ); return; }
if( pQueue->pPrinter ) OldStatus = pQueue->pPrinter->Status; else OldStatus = PRINTER_STATUS_UNKNOWN; }
if( !IsIconic( hwndFrame ) // && !pInfo->RefreshSignal && !IsIconic( hWnd )
/* && IsWindowReallyVisible( hWnd ) */ ) /* ^^^^^^^^^^^^^^^^^^^^^ watch this space for new API from scottlu */ { if( hWnd == (HWND)SendMessage(hwndClient, WM_MDIGETACTIVE, 0, 0L)) EnableCheckTBButtons(hWnd); }
LEAVE_PROTECTED_DATA( pInfo );
if( CheckStatus ) { if( pQueue->pPrinter ) { ENTER_PROTECTED_DATA( pInfo );
if( _tcscmp( pQueue->pPrinterName, pQueue->pPrinter->pPrinterName ) ) { ReallocSplStr( &pQueue->pPrinterName, pQueue->pPrinter->pPrinterName ); PrinterNameChanged = TRUE; }
NewStatus = pQueue->pPrinter->Status;
LEAVE_PROTECTED_DATA( pInfo ); } else { //
// !! BUGBUG !!
//
// This GetLastError() call looks bogus.
//
if( GetLastError() == ERROR_ACCESS_DENIED ) NewStatus = PRINTER_STATUS_ACCESS_DENIED; else NewStatus = PRINTER_STATUS_UNKNOWN; }
if( ( OldStatus != NewStatus ) || PrinterNameChanged ) { ENTER_PROTECTED_DATA( pInfo );
SetPrinterTitle( hWnd, pQueue->pPrinterName, NewStatus );
LEAVE_PROTECTED_DATA( pInfo );
/* Hack to ensure listbox is redrawn when connexion is re-established:
*/ if( OldStatus == PRINTER_STATUS_UNKNOWN ) { InvalidateRect( pQueue->pMDIWinInfo->hwndList, NULL, TRUE ); } } } }
#ifdef OLDSTUFF
/*
* */ VOID MDIStatusChanged( HWND hwnd ) { PMDIWIN_INFO pInfo; PQUEUE pQueue;
pInfo = GETMDIWIN( hwnd );
if( pInfo->WindowType != MDIWIN_SERVER ) { pQueue = (PQUEUE)pInfo->pContext;
ENTER_PROTECTED_DATA( pInfo );
SetPrinterTitle( hwnd, pQueue->pPrinterName, pQueue->pPrinter->Status );
LEAVE_PROTECTED_DATA( pInfo ); } } #endif /* OLDSTUFF */
/*
* */ VOID MDIUpdateList( HWND hwnd ) { PMDIWIN_INFO pInfo; DWORD CurSel; BOOL PrinterWasSet = FALSE; RECT rcList; DWORD TopIndex; DWORD BottomIndex;
pInfo = GETMDIWIN( hwnd );
DBGMSG( DBG_TRACE, ( "WM_UPDATE_LIST\n" ) );
ENTER_PROTECTED_DATA( pInfo );
SendMessage( pInfo->hwndList, WM_SETREDRAW, 0, 0L );
/* Keep the listbox item count in sync with the number of objects on display:
*/ if( SendMessage( pInfo->hwndList, LB_GETCOUNT, 0, 0L ) != (int)*pInfo->pcObjects ) { /* We have to go through hoops here since the nodata listbox
* is so brain dead. When you set the count, it invalidates * the list and sets the top index to 0... */ CurSel = SendMessage( pInfo->hwndList, LB_GETCURSEL, 0, 0L ); SendMessage( pInfo->hwndList, LB_SETCOUNT, *pInfo->pcObjects, 0L ); SendMessage( pInfo->hwndList, LB_SETCURSEL, CurSel, 0L ); }
if( pInfo->ObjSelected == NOSELECTION ) { SendMessage( pInfo->hwndList, LB_SETCURSEL, (WPARAM)-1, 0L ); }
/* If the selected item is currently visible, make sure it
* corresponds to the item that the system thinks is selected: */ else if( ( pInfo->ObjSelected >= *pInfo->pFirstEnumObj ) &&( pInfo->ObjSelected < ( *pInfo->pFirstEnumObj + pInfo->cNumLines ) ) &&( SendMessage( pInfo->hwndList, LB_GETCURSEL, 0, 0L ) != (int)pInfo->ObjSelected ) ) { SendMessage( pInfo->hwndList, LB_SETCURSEL, pInfo->ObjSelected, 0L ); }
ValidateRect( pInfo->hwndList, NULL ); SendMessage( pInfo->hwndList, WM_SETREDRAW, 1, 0L );
SetMDITitle( hwnd, pInfo );
/* Don't erase the background for the part of the listbox with items in it,
* but ensure that the rest is completely redrawn, otherwise we may leave * things lying around: */ GetClientRect( pInfo->hwndList, &rcList );
TopIndex = (DWORD)SendMessage( pInfo->hwndList, LB_GETTOPINDEX, 0, 0L );
DBGMSG( DBG_TRACE, ( "Top Index: %d\n", TopIndex ) );
if( TopIndex != (DWORD)-1 ) { BottomIndex = ( *pInfo->pcObjects - TopIndex );
DBGMSG( DBG_TRACE, ( "Bottom Index: %d\n", BottomIndex ) );
rcList.bottom = min( rcList.bottom, (LONG)( BottomIndex * STATUS_BITMAP_HEIGHT ) );
DBGMSG( DBG_TRACE, ( "Invalidate %d, %d, %d, %d, FALSE\n", rcList.left, rcList.top, rcList.right, rcList.bottom ) );
InvalidateRect( pInfo->hwndList, &rcList, FALSE ); UpdateWindow( pInfo->hwndList );
GetClientRect( pInfo->hwndList, &rcList ); rcList.top = min( rcList.bottom, (LONG)( BottomIndex * STATUS_BITMAP_HEIGHT ) ); }
DBGMSG( DBG_TRACE, ( "Invalidate %d, %d, %d, %d, TRUE\n", rcList.left, rcList.top, rcList.right, rcList.bottom ) );
InvalidateRect( pInfo->hwndList, &rcList, TRUE ); UpdateWindow( pInfo->hwndList );
if( pInfo->hwnd == (HWND)SendMessage( hwndClient, WM_MDIGETACTIVE, 0, 0L ) ) { UpdateStatus( pInfo->hwnd ); EnableCheckTBButtons( pInfo->hwnd ); }
if( (!( pInfo->Changes & PRINTER_CHANGE_TIMEOUT ) ) &&( pInfo->Changes & PRINTER_CHANGE_SET_PRINTER ) ) PrinterWasSet = TRUE;
if( PrinterWasSet ) UpdateDefaultList();
LEAVE_PROTECTED_DATA( pInfo );
/* Ensure that any relevant changes (e.g. port for default printer)
* get updated in WIN.INI for the benefit of Win31 apps. * Do this by faking a change in the default printer. * (Fixes bug #6011.) * * Moved from PrtPropCommandOK(). */
//
// szDefaultPrinter updated in the call to UpdateDefaultList above.
//
if( PrinterWasSet ) ToolbarCommandSelChange(TRUE); }
/* MDISetParts
* * Called after creation to set the column widths. * Pass the message on to the header window. */ VOID MDISetParts( HWND hwnd, WPARAM wParam, LPARAM lParam ) { PMDIWIN_INFO pInfo;
if( pInfo = GETMDIWIN( hwnd ) ) { SendMessage( pInfo->hwndHeader, SB_SETPARTS, wParam, lParam ); } }
/*
* */ VOID MDIDestroy( HWND hwnd ) { PMDIWIN_INFO pInfo;
pInfo = GETMDIWIN( hwnd );
ENTER_PROTECTED_DATA( pInfo );
KillMDIWinInfo(pInfo);
switch( pInfo->WindowType ) { case MDIWIN_LOCALPRINTER: case MDIWIN_NETWORKPRINTER: case MDIWIN_LOCALNETWORKPRINTER: if( ((PQUEUE)(pInfo->pContext))->hPrinter ) {
ClosePrinter( ((PQUEUE)(pInfo->pContext))->hPrinter ); ((PQUEUE)(pInfo->pContext))->hPrinter = NULL; } break;
case MDIWIN_SERVER: if( ((PSERVER_CONTEXT)(pInfo->pContext))->hServer ) { ClosePrinter( ((PSERVER_CONTEXT)(pInfo->pContext))->hServer ); ((PSERVER_CONTEXT)(pInfo->pContext))->hServer = NULL; } break; }
LEAVE_PROTECTED_DATA( pInfo ); }
/*
* */ LONG MDIDragList( HWND hwnd, LPDRAGLISTINFO pDragInfo ) { PMDIWIN_INFO pInfo; PQUEUE pPrinterContext; DWORD DragPosition;
if( !( pInfo = GETMDIWIN( hwnd ) ) ) return 0;
if( !( pPrinterContext = pInfo->pContext ) ) return 0;
/* You have to be an administrator on the printer to reorder jobs:
*/ if( !( pPrinterContext->AccessGranted & PRINTER_ACCESS_ADMINISTER ) ) return 0;
if( *pInfo->pcObjects < 1 ) return 0;
DragPosition = LBItemFromPt( pDragInfo->hWnd, pDragInfo->ptCursor, TRUE );
switch( pDragInfo->uNotification ) { case DL_BEGINDRAG: ENTER_PROTECTED_DATA( pInfo ); ResetEvent( pInfo->RefreshSignal ); LEAVE_PROTECTED_DATA( pInfo ); return -1;
case DL_DRAGGING: if( DragPosition < *pInfo->pcObjects ) { MarkPosition( pInfo, DragPosition ); SetCursor( hcursorReorder ); return -1; } else return DL_STOPCURSOR;
case DL_DROPPED: if( DragPosition != pInfo->ObjSelected ) ReorderJob( hwnd, pInfo, DragPosition );
// drop through...
case DL_CANCELDRAG: MarkPosition( pInfo, NOSELECTION ); ENTER_PROTECTED_DATA( pInfo ); SetEvent( pInfo->RefreshSignal ); LEAVE_PROTECTED_DATA( pInfo ); }
return 0; }
VOID SubclassListboxKeyDown( HWND hwnd, INT VKey ); VOID SubclassListboxKeyUp( HWND hwnd, INT VKey );
/* Subclass window procedure for MDI printer listbox containing jobs.
* Server viewers are not subclassed. */ long SubclassListboxWndProc( HWND hwnd, UINT message, WPARAM wParam, LONG lParam ) { switch( message ) { case WM_KEYDOWN: SubclassListboxKeyDown( hwnd, (INT)wParam ); break;
case WM_KEYUP: SubclassListboxKeyUp( hwnd, (INT)wParam ); break; } return CallWindowProc( DefListboxWndProc, hwnd, message, wParam, lParam ); }
/* This catches the delete key being pressed.
* If there is a job selected, go ahead and delete it. * We don't respond if a printer currently has the focus. */ VOID SubclassListboxKeyDown( HWND hwnd, INT VKey ) { PMDIWIN_INFO pInfo;
if( VKey == VK_DELETE ) { pInfo = GETMDIWIN( GetParent( hwnd ) ); if( !pInfo ) return;
/* If there's a current selection, fake a Remove Document command:
*/ if( pInfo->ObjSelected != NOSELECTION ) SendMessage( hwndFrame, WM_COMMAND, MAKEWPARAM( IDM_REMOVEDOC, 0 ), 0 ); } }
/* This handles the case where the user releases the control key
* whilst dragging a job using the cursor keys. * This completes the drag operation. */ VOID SubclassListboxKeyUp( HWND hwnd, INT VKey ) { PMDIWIN_INFO pInfo; DWORD NewPos;
if( VKey == VK_CONTROL ) { pInfo = GETMDIWIN( GetParent( hwnd ) ); if( !pInfo ) return;
if( ( pInfo->DragPosition != NOSELECTION ) &&( pInfo->ObjSelected != pInfo->DragPosition ) ) { NewPos = pInfo->DragPosition; ReorderJob( GetParent( hwnd ), pInfo, pInfo->DragPosition ); MarkPosition( pInfo, NOSELECTION ); SETLISTSELECT( GetParent( hwnd ), ID_OBJLIST, NewPos ); SetEvent( pInfo->RefreshSignal ); LEAVE_PROTECTED_DATA( pInfo ); } } }
VOID Refresh( HWND hwnd, PMDIWIN_INFO pInfo, DWORD RepaintOption) { DWORD Changed; DWORD TopIndex; DWORD MutexStatus;
if( !pInfo ) return;
if (pInfo->WindowType == MDIWIN_SERVER) { /* This can't happen, we've grayed out the menu-item for
* server mdi windows. Anyway, let's bomb out */ return;
}
//
// If still loading, return now since the worker thread
// is initializing and will refresh when it can.
//
if (pInfo->Status & PRINTER_STATUS_LOADING) return;
/* access protected area of pInfo with "zero"
* timeout. if we couldn't access, then quit here * RefreshThread is in the middle of an update. * let it take care of the refreshing. */
MutexStatus = WaitForSingleObject(pInfo->DataMutex, 0);
if (MutexStatus == -1) { // Couldn't acquire the mutex
return; }
if (MutexStatus == WAIT_TIMEOUT) { /* This means RefreshThread has ownership of the
mutex -- it will take care of updating -- return */ return; }
/* We own the DataMutex at this point */
TopIndex = SendMessage( pInfo->hwndList, LB_GETTOPINDEX, 0, 0L );
/* Enumerate a buffer big enough to page up once ...
*/
*pInfo->pFirstEnumObj = (DWORD)max( 0, (int)TopIndex - (int)pInfo->cNumLines );
SetCursor( hcursorWait ); ENTER_PROTECTED_DATA(pInfo);
if( pInfo->pfnRefresh ) { //
// *pInfo->phWaitObject should be NULL if the OpenPrinter
// fails... but OpenPrinter will succeed even if the
// remote printer is not available (probably for winword),
// So add unknown here also.
//
if (pInfo->Status & PRINTER_STATUS_UNKNOWN || !*pInfo->phWaitObject) { //
// We have an unknown connection; try and reopen
// when refresh, in case the admin gave us
// access recently. Or possibly the net was down...
//
if (*pInfo->phWaitObject) { ClosePrinter(*pInfo->phWaitObject); *pInfo->phWaitObject = NULL; }
ReopenPrinter( pInfo->pContext, pInfo->WindowType, TRUE ); }
Changed = PRINTER_CHANGE_JOB|PRINTER_CHANGE_PRINTER; (*pInfo->pfnRefresh)( pInfo->pContext, &Changed ); }
LEAVE_PROTECTED_DATA(pInfo); SetCursor( hcursorArrow );
/* REPAINT_FORCE makes sense only when we definitely want the list
* to repaint even if there have been no changes to its contents. * The only time this should happen is when the refresh is in response * to the user's selecting the Refresh menu option: */ if( ( Changed && ( RepaintOption == REPAINT_IF_CHANGED ) ) ||( RepaintOption == REPAINT_FORCE ) ) { /* Keep the listbox item count in sync with the number of objects on display:
* Originally, this code was duplicating the MDIUpdateList function. So let's just * send a WM_UPDATELIST message to the MDI window to take care of the rest. */ PostMessage(pInfo->hwnd, WM_UPDATE_LIST, (WPARAM)pInfo, 0L); }
ReleaseMutex(pInfo->DataMutex);
return;
}
/*
* */ BOOL RefreshServerContext( PVOID pContext, PDWORD pFlags ) { PSERVER_CONTEXT pServerContext; LPTSTR pCurrentSelection = NULL; DWORD Error = NO_ERROR;
pServerContext = (PSERVER_CONTEXT)pContext;
ENTER_PROTECTED_DATA( pServerContext->pMDIWinInfo );
//
// Don't change the default printer here since the set printer
// was remote.
//
*pFlags &= ~PRINTER_CHANGE_SET_PRINTER;
/* We may end up having to reallocate the buffer, so make sure we keep track
* of the name of the currently selected printer: */ if( pServerContext->pSelPrinter ) pCurrentSelection = AllocSplStr( pServerContext->pSelPrinter->pPrinterName );
if( ENUM_PRINTERS( PRINTER_ENUM_NAME, pServerContext->pServerName, 2, pServerContext->pPrinters, pServerContext->cbPrinters, &pServerContext->cbPrinters, &pServerContext->cPrinters ) ) { DWORD i = 0;
pServerContext->cEnumPrinters = pServerContext->cPrinters;
/* Find the printer name that matches the current selection:
*/ if( pCurrentSelection ) { while( ( i < pServerContext->cPrinters ) && _tcscmp( pServerContext->pPrinters[i].pPrinterName, pCurrentSelection ) ) i++; }
if( i < pServerContext->cPrinters ) { pServerContext->pSelPrinter = &pServerContext->pPrinters[i]; pServerContext->SelPrinterId = i; pServerContext->pMDIWinInfo->ObjSelected = i; } else { pServerContext->pSelPrinter = &pServerContext->pPrinters[0]; pServerContext->SelPrinterId = 0; } }
else { pServerContext->SelPrinterId = 0; pServerContext->pSelPrinter = NULL; pServerContext->pMDIWinInfo->ObjSelected = NOSELECTION; Error = GetLastError( ); }
if( pCurrentSelection ) FreeSplStr( pCurrentSelection );
pServerContext->Error = Error;
LEAVE_PROTECTED_DATA( pServerContext->pMDIWinInfo );
return ( Error == NO_ERROR );
}
/* Message
* * Displays a message by loading the strings whose IDs are passed into * the function, and substituting the supplied variable argument list * using the varargs macros. * */ int Message(HWND hwnd, DWORD Type, int CaptionID, int TextID, ...) { TCHAR MsgText[MAX_PATH*2]; TCHAR MsgFormat[520]; TCHAR MsgCaption[80]; va_list vargs;
if( ( LoadString( hInst, TextID, MsgFormat, sizeof MsgFormat / sizeof *MsgFormat ) > 0 ) && ( LoadString( hInst, CaptionID, MsgCaption, sizeof MsgCaption / sizeof *MsgCaption ) > 0 ) ) { va_start( vargs, TextID ); wvsprintf( MsgText, MsgFormat, vargs ); va_end( vargs );
return MessageBox(hwnd, MsgText, MsgCaption, Type); } else return 0; }
FARPROC LoadLibraryGetProcAddress(HWND hwnd, LPTSTR LibraryName, LPCSTR ProcName, PHANDLE phLibrary) { HANDLE hLibrary; FARPROC lpfn = NULL;
hLibrary = LoadLibrary(LibraryName);
if(hLibrary) { lpfn = GetProcAddress(hLibrary, ProcName);
if(!lpfn) { Message(hwnd, MSG_ERROR, IDS_PRINTMANAGER, IDS_COULDNOTFINDPROCEDURE, ProcName, LibraryName);
FreeLibrary(hLibrary); } } else Message(hwnd, MSG_ERROR, IDS_PRINTMANAGER, IDS_COULDNOTLOADLIBRARY, LibraryName);
*phLibrary = hLibrary;
return lpfn; }
/* Returns the positions saved in the registry of windows and headers.
* Return code is TRUE if the information is found, FALSE otherwise. * If there is no information found, default values are substituted * for the window position, but no default header values are assigned. * */ BOOL GetSavedWindowPos( LPTSTR pKey, LPTSTR WindowName, PSAVEDWINDOWPOS pswp, DWORD cHeaders, PINT pHeaders ) { PREGISTRY_DATA pRegistryData; DWORD cbRegistryData; DWORD rc; DWORD i; PINT pint;
/* Get the size of the fixed part of the registry data:
*/ cbRegistryData = ( sizeof( REGISTRY_DATA ) - sizeof( pRegistryData->Headers ) );
cbRegistryData += ( cHeaders * sizeof( pRegistryData->Headers ) );
pRegistryData = AllocSplMem( cbRegistryData );
RegistryEntries.Size = cbRegistryData;
rc = ReadRegistryData( pKey, WindowName, (LPBYTE)pRegistryData, &RegistryEntries );
if( rc == NO_ERROR ) { pswp->left = pRegistryData->WindowPlacement.rcNormalPosition.left; pswp->top = pRegistryData->WindowPlacement.rcNormalPosition.top; pswp->width = pRegistryData->WindowPlacement.rcNormalPosition.right - pswp->left; pswp->height = pRegistryData->WindowPlacement.rcNormalPosition.bottom - pswp->top; pswp->xicon = pRegistryData->WindowPlacement.ptMinPosition.x; pswp->yicon = pRegistryData->WindowPlacement.ptMinPosition.y; pswp->sw = pRegistryData->WindowPlacement.showCmd; pswp->options = pRegistryData->Options;
for( i = 0; i < cHeaders; i++ ) pHeaders[i] = pRegistryData->Headers[i]; } else { /* No data retrieved from the registry:
* Substitute default values: */ pint = (PINT)pswp;
for( i = 0; i < RECTSIDES; i++ ) pint[i] = CW_USEDEFAULT;
for( i = RECTSIDES; i < INIVALUES; i++ ) pint[i] = 0;
pswp->sw = SW_NORMAL; }
FreeSplMem( pRegistryData );
return ( rc == NO_ERROR ); }
// int _CRTAPI1
HWND GetRealParent( HWND hwnd ) { // run up the parent chain until you find a hwnd
// that doesn't have WS_CHILD set
while( GetWindowLong( hwnd, GWL_STYLE ) & WS_CHILD ) hwnd = (HWND)GetWindowLong( hwnd, GWL_HWNDPARENT );
return hwnd; }
#ifdef OLDSTUFF
/* MessageProc
* * This is the callback routine which hooks F1 keypresses in menus and dialog boxes. * * Any such message will be repackaged as a WM_Help message and sent to the frame. * * Two codes are handled: * * MSGF_MENU - In this case, the message originates in a menu item, * and the hwnd parameter of pMsg contains the menu handle. * We get the ID of the currently selected menu item. * * MSGF_DIALOGBOX - In this case, the message originates in a dialog box, * and the hwnd parameter of pMsg contains the dialog item handle. * We get its control ID. * * * See the Win32 API programming reference for a description of how this * routine works. * * Andrew Bell (andrewbe) - 2 September 1992 */ LRESULT CALLBACK MessageProc( int Code, WPARAM wParam, LPARAM lParam ) { PMSG pMsg = (PMSG)lParam;
if( Code < 0 ) return CallNextHookEx( hhookMessage, Code, wParam, lParam );
switch( Code ) { case MSGF_MENU: if( ( pMsg->message == WM_KEYDOWN ) && ( pMsg->wParam == VK_F1 ) ) { PostMessage( hwndFrame, WM_Help, (LPARAM)pMsg->hwnd, WinHelpMenuID ); // GetCurrentMenuItemID( GetMenu( hwndFrame ) ) );
return 1; } break;
case MSGF_DIALOGBOX: if( ( pMsg->message == WM_KEYDOWN ) && ( pMsg->wParam == VK_F1 ) ) { PostMessage( GetRealParent( pMsg->hwnd ), WM_Help, (WPARAM)pMsg->hwnd, 0 ); return 1; } break; }
return 0; }
#endif /* OLDSTUFF */
/* GetMsgProc
* * This is the callback routine which hooks F1 keypresses. * * Any such message will be repackaged as a WM_Help message and sent to the * top window, which may be the frame window or a dialog box. * * See the Win32 API programming reference for a description of how this * routine works. * * Changed from previous MessageProc so that F1 in the Default Printer combo * will also be hooked. * * Andrew Bell (andrewbe) - 4 February 1993 */ LRESULT CALLBACK GetMsgProc( int Code, WPARAM wParam, LPARAM lParam ) { PMSG pMsg = (PMSG)lParam;
if( Code < 0 ) return CallNextHookEx( hhookGetMsg, Code, wParam, lParam );
if( ( pMsg->message == WM_KEYDOWN ) && ( pMsg->wParam == VK_F1 ) ) { PostMessage( GetRealParent( pMsg->hwnd ), WM_Help, (LPARAM)pMsg->hwnd, WinHelpMenuID ); }
return 0; }
/* GetCurrentMenuItemID
* * Returns the ID of the currently selected item in a menu. * * There's no easy way to do this, unfortunately, so we have to enumerate * all the menu items until we find one with the MF_HILITE flag set. * * The routine scans only one level of menus, so you'll have to modify * it if you want to use it for multiple-level menus. * * Parameter: * * hMenu - The handle of the menu to be searched. * * Returns: * * The ID of the highlighted menu item, * or 0 if no highlighted item was found or if an error occurred. * * Andrew Bell (andrewbe) - 2 September 1992 */ UINT GetCurrentMenuItemID( HMENU hMenu ) { UINT MenuItemID = 0; int MenuItemCount, iMain; int SubMenuItemCount, iSub; HMENU hSubMenu; UINT MenuState;
/* Find out how many top-level pull-downs there are:
*/ MenuItemCount = GetMenuItemCount( hMenu );
/* If there was an error, just set the count to zero,
* and it will fall through: */ if( MenuItemCount == -1 ) MenuItemCount = 0;
iMain = 0;
/* Now go through each pull-down until we find a selected item:
*/ while( ( MenuItemID == 0 ) && ( iMain < MenuItemCount ) ) { hSubMenu = GetSubMenu( hMenu, iMain );
SubMenuItemCount = GetMenuItemCount( hSubMenu );
if( SubMenuItemCount == -1 ) SubMenuItemCount = 0;
iSub = 0;
while( ( MenuItemID == 0 ) && ( iSub < SubMenuItemCount ) ) { MenuState = GetMenuState( hSubMenu, iSub, MF_BYPOSITION );
if( MenuState != (UINT)-1 ) { if( (BYTE)MenuState & MF_HILITE ) { MenuItemID = GetMenuItemID( hSubMenu, iSub );
/* Hack for MDI windows listed under "Window".
* Return the generic help ID: */ if( ( iMain == POPUP_WINDOW ) &&( ( MenuItemID < IDM_CASCADE ) || ( MenuItemID > IDM_REFRESH ) ) ) MenuItemID = ID_HELP_MDIWINDOW; } }
iSub++; }
iMain++; }
return MenuItemID; }
VOID KillMDIWinInfo( PMDIWIN_INFO pInfo) { pInfo->Alive = FALSE; }
/* Checks to see whether there is already an instance of Print Manager running.
* If so, it brings it to the foreground and returns TRUE. * * Body of the function borrowed from WinFile. */ BOOL PreviousPrintManagerInstanceFound( ) { HWND hwndPrev; HWND hwnd;
hwndPrev = FindWindow (szPrintManagerClass, NULL);
if (hwndPrev != NULL) { hwnd = GetLastActivePopup(hwndPrev);
if (IsIconic(hwndPrev)) ShowWindow (hwndPrev, SW_RESTORE);
SetForegroundWindow (hwnd);
return TRUE; }
return FALSE; }
#define WAIT_OBJECT_MESSAGE_WRITTEN 0
#define WAIT_OBJECT_NOTIFY_CHANGE_KEY_VALUE 1
#define WAIT_OBJECT_COUNT 2
int #if !defined(_MIPS_) && !defined(_ALPHA_) && !defined(_PPC_)
_cdecl #endif
main( unsigned argc, CHAR **argv ) { MSG msg; HANDLE hInstance = NULL; HANDLE hAccel; SAVEDWINDOWPOS swp; PRINTMAN_DATA PrintManData; TCHAR strPrintManager[40]; DWORD EventId; BOOL Quit = FALSE; REGISTRY_ENTRY RegistrySaveSettings = { REG_DWORD, sizeof(DWORD) }; TCHAR SaveSettings[40]; HANDLE hWaitObjects[WAIT_OBJECT_COUNT]; HKEY hWindowsKey; LCID lcid; TCHAR szSystemDir[MAX_PATH]; STARTUPINFO si; WCHAR Buffer[128];
#ifdef HEAPCHECK
HeapCheckInit(); #endif
lcid = GetThreadLocale(); bJapan = (PRIMARYLANGID(LANGIDFROMLCID(lcid)) == LANG_JAPANESE);
if( PreviousPrintManagerInstanceFound( ) ) return FALSE;
ThousandSeparator = TEXT(','); if (GetLocaleInfoW (lcid, LOCALE_STHOUSAND, Buffer, 128)) { ThousandSeparator = Buffer[0]; }
hInstance = GetModuleHandle (NULL);
if (!InitApplication(hInstance, &hAccel)) return(FALSE);
// Might as well open the registry key now.
RegCreateKeyEx(HKEY_CURRENT_USER, szRegistryPrinter, 0, NULL, 0, KEY_READ | KEY_WRITE, NULL, &hPrinterKey, NULL);
// Create the main Print Manager frame window
LoadString(hInstance, IDS_PRINTMANAGER, strPrintManager, sizeof(strPrintManager) / sizeof(*strPrintManager));
GetSavedWindowPos( NULL, strPrintManager, &swp, 0, NULL ); bToolBar = !( swp.options & OPTION_NOTOOLBAR ); bStatusBar = !( swp.options & OPTION_NOSTATUSBAR ); bSaveSettings = TRUE;
LoadString(hInstance, IDS_SAVE_SETTINGS, SaveSettings, sizeof SaveSettings / sizeof *SaveSettings);
ReadRegistryData( NULL, SaveSettings, (LPBYTE)&bSaveSettings, &RegistrySaveSettings );
hhookGetMsg = SetWindowsHookEx( WH_GETMESSAGE, GetMsgProc, NULL, GetCurrentThreadId( ) );
WM_Help = RegisterWindowMessage( TEXT("Print Manager Help Message") );
CreateWindow(szPrintManagerClass, strPrintManager, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, swp.left, swp.top, swp.width, swp.height, NULL, NULL, hInstance, &PrintManData);
if (GetSystemDirectory(szSystemDir, sizeof(szSystemDir)/sizeof(szSystemDir[0]))) {
SetCurrentDirectory(szSystemDir); }
// Let the program manager over ride the saved window position
GetStartupInfo(&si);
if (si.wShowWindow == SW_MINIMIZE || si.wShowWindow == SW_SHOWMINNOACTIVE) { ShowWindow(hwndFrame, si.wShowWindow); } else { ShowWindow(hwndFrame, swp.sw); }
UpdateWindow(hwndFrame);
hWaitObjects[WAIT_OBJECT_MESSAGE_WRITTEN] = ThreadMessageWritten; hWaitObjects[WAIT_OBJECT_NOTIFY_CHANGE_KEY_VALUE] = CreateEvent( NULL, EVENT_RESET_AUTOMATIC, EVENT_INITIAL_STATE_NOT_SIGNALED, NULL );
if( RegOpenKey( HKEY_CURRENT_USER, TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows"), &hWindowsKey ) != NO_ERROR ) { DBGMSG( DBG_WARNING, ( "RegOpenKey failed\n" ) ); }
/* Ask for notification of changes to last write time of registry key.
* Empirically found to work. I'm buggered if I know why this works, * whereas REG_NOTIFY_CHANGE_ATTRIBUTES and REG_NOTIFY_CHANGE_NAME * don't seem to have any effect. */ if( RegNotifyChangeKeyValue( hWindowsKey, FALSE, REG_NOTIFY_CHANGE_LAST_SET, hWaitObjects[WAIT_OBJECT_NOTIFY_CHANGE_KEY_VALUE], TRUE ) != NO_ERROR ) { DBGMSG( DBG_WARNING, ( "RegNotifyChangeKeyValue failed\n" ) ); }
while( ( Quit == FALSE ) &&( ( EventId = MsgWaitForMultipleObjects( WAIT_OBJECT_COUNT, hWaitObjects, FALSE, INFINITE, QS_ALLEVENTS | QS_SENDMESSAGE ) ) != (DWORD)-1 ) ) { if( EventId == WAIT_OBJECT_0 + WAIT_OBJECT_MESSAGE_WRITTEN ) { DBGMSG( DBG_TRACE, ( "Dispatching message %08x\n", ThreadMessage.message ) ); DISPATCH_THREAD_MESSAGE( &ThreadMessage ); }
else if( EventId == ( WAIT_OBJECT_0 + WAIT_OBJECT_NOTIFY_CHANGE_KEY_VALUE ) ) { if( !ExpectingNotifyChangeKeyValue ) { DBGMSG( DBG_TRACE, ( "NotifyChangeKeyValue received\n" ) );
PostMessage( hwndFrame, WM_REG_NOTIFY_CHANGE_KEY_VALUE, (WPARAM)hWindowsKey, 0 ); }
else { DBGMSG( DBG_TRACE, ( "NotifyChangeKeyValue received (expected)\n" ) );
ExpectingNotifyChangeKeyValue = FALSE; }
RegNotifyChangeKeyValue( hWindowsKey, FALSE, REG_NOTIFY_CHANGE_LAST_SET, hWaitObjects[WAIT_OBJECT_NOTIFY_CHANGE_KEY_VALUE], TRUE ); }
else { while( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) { //
// since we use RETURN as an accelerator we have to manually
// restore ourselves when we see VK_RETURN and we are minimized
//
if (msg.message == WM_SYSKEYDOWN && msg.wParam == VK_RETURN && IsIconic(hwndFrame)) {
ShowWindow(hwndFrame, SW_NORMAL); } else if( !TranslateMDISysAccel( hwndClient, &msg ) && !TranslateAccelerator( hwndFrame, hAccel, &msg ) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); }
if( msg.message == WM_QUIT ) { Quit = TRUE; break; } } } }
CloseHandle( ThreadMessageWritten ); CloseHandle( ThreadMessageRead );
RegCloseKey(hWindowsKey); RegCloseKey(hPrinterKey);
#ifdef HEAPCHECK
HeapCheckDump(0); HeapCheckDestroy(); #endif
return msg.wParam;
UNREFERENCED_PARAMETER(argc); UNREFERENCED_PARAMETER(argv); }
|