mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
7677 lines
207 KiB
7677 lines
207 KiB
/*---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);
|
|
}
|