|
|
#include "pch.h"
#pragma hdrstop
#include <initguid.h>
#include "winprtp.h"
/*-----------------------------------------------------------------------------
/ Local functions / data /----------------------------------------------------------------------------*/
static TCHAR c_szColor[] = TEXT("color"); static TCHAR c_szDuplex[] = TEXT("duplex"); static TCHAR c_szStaple[] = TEXT("stapling"); static TCHAR c_szResolution[] = TEXT("resolution"); static TCHAR c_szSpeed[] = TEXT("speed"); static TCHAR c_szPaperSize[] = TEXT("size"); static TCHAR c_szPrintPaperSize[] = TEXT("(printMediaReady=%s*)"); static TCHAR c_szPrintResolution[] = TEXT("(printMaxResolutionSupported>=%s)"); static TCHAR c_szPrintSpeed[] = TEXT("(printPagesPerMinute>=%d)"); static TCHAR c_szLocationQuery[] = TEXT("(location=%s*)"); static TCHAR c_szLocationQueryComplex[] = TEXT("(|(location=%s/*)(location=%s))"); static TCHAR c_szBlank[] = TEXT(""); static TCHAR c_szLocationTag[] = TEXT("Location"); static TCHAR c_szDynamicTag[] = TEXT("$DynamicLocation$"); static TCHAR c_szPrinterPolicy[] = TEXT("Software\\Policies\\Microsoft\\Windows NT\\Printers"); static TCHAR c_szPhysicalLocationFeature[] = TEXT("PhysicalLocationSupport");
static WCHAR c_szPrinterName[] = L"printerName"; static WCHAR c_szServerName[] = L"serverName"; static WCHAR c_szQueryPrefix[] = L"(uncName=*)(objectCategory=printQueue)"; static WCHAR c_szPrintColor[] = L"(printColor=TRUE)"; static WCHAR c_szPrintDuplex[] = L"(printDuplexSupported=TRUE)"; static WCHAR c_szPrintStapling[] = L"(printStaplingSupported=TRUE)"; static WCHAR c_szPrintModelProp[] = L"driverName";
#define MAX_LOCATION_WAIT_TIME 30000
#define MAX_LOCATION_MSG_WAIT_TIME 60000
#define MAX_LOCATION MAX_PATH
static LPWSTR c_szClassList[] = { L"printQueue", };
static PAGECTRL ctrls1[] = { IDC_PRINTNAME, c_szPrinterName, FILTER_CONTAINS, IDC_PRINTMODEL, c_szPrintModelProp, FILTER_CONTAINS, };
static COLUMNINFO columns[] = { 0, 0, IDS_CN, 0, c_szPrinterName, 0, 0, IDS_LOCATION, 0, c_szLocation, 0, 0, IDS_MODEL, 0, c_szPrintModelProp, 0, 0, IDS_SERVERNAME, 0, c_szServerName, 0, DEFAULT_WIDTH_DESCRIPTION, IDS_COMMENT, 0, c_szDescription, };
static struct { INT idString; LPCTSTR szString; } Resolutions [] = { IDS_ANY, NULL, IDS_72, TEXT("72"), IDS_144, TEXT("144"), IDS_300, TEXT("300"), IDS_600, TEXT("600"), IDS_1200, TEXT("1200"), IDS_2400, TEXT("2400"), IDS_4800, TEXT("4800"), IDS_9600, TEXT("9600"), IDS_32000, TEXT("32000"), };
#define IDH_NOHELP ((DWORD)-1) // Disables Help for a control
static const DWORD aFormHelpIDs[]= { IDC_PRINTNAME, IDH_PRINTER_NAME, IDC_PRINTLOCATION, IDH_PRINTER_LOCATION, IDC_PRINTBROWSE, IDH_PRINTER_LOCATION, IDC_PRINTMODEL, IDH_PRINTER_MODEL, IDC_PRINTDUPLEX, IDH_DOUBLE_SIDED, IDC_PRINTSTAPLE, IDH_STAPLE, IDC_PRINTCOLOR, IDH_PRINT_COLOR, IDC_PRINTPAGESIZE, IDH_PAPER_SIZE, IDC_PRINTRES, IDH_RESOLUTION, IDC_PRINTRES_POSTFIX, IDH_RESOLUTION, IDC_PRINTSPEED, IDH_SPEED, IDC_PRINTSPEED_UPDN,IDH_SPEED, IDC_PRINTSPEED_POSTFIX, IDH_SPEED, IDC_SEPLINE, IDH_NOHELP, 0, 0, };
/*-----------------------------------------------------------------------------
/ CPrintQueryPage class /----------------------------------------------------------------------------*/ class CPrintQueryPage { public:
CPrintQueryPage( HWND hwnd ); ~CPrintQueryPage(); HRESULT Initialize( HWND hwnd, BOOL bSynchronous ); LPCTSTR GetSearchText( VOID ); UINT AddRef( VOID ); UINT Release( VOID ); VOID TimerExpire(); VOID EnableLocationEditText( HWND hwnd, BOOL bEnable ); VOID LocationEditTextChanged( HWND hwnd ); VOID BrowseForLocation( HWND hwnd ); HRESULT PersistLocation(HWND hwnd, IPersistQuery* pPersistQuery, BOOL fRead); VOID OnInitDialog( HWND hwnd );
private:
CPrintQueryPage( CPrintQueryPage &rhs ); CPrintQueryPage & operator=( CPrintQueryPage &rhs );
VOID WaitForLocation( HWND hwnd ); DWORD Discovery( VOID ); VOID TimerCreate( VOID ); VOID TimerRelease( VOID ); VOID SetLocationText( HWND hCtrl, LPCTSTR pszString, BOOL fReadOnly, BOOL fIgnoreWorkingText ); static DWORD WINAPI _PhysicalLocationThread( PVOID pVoid );
IPhysicalLocation *m_pPhysicalLocation; LPTSTR m_pszPhysicalLocation; LONG m_cRef; HWND m_hCtrl; BOOL m_fThreadCreated; BOOL m_fComplete; BOOL m_fLocationEnableState; BOOL m_fLocationUserModified; BOOL m_bValid; HWND m_hwnd; UINT_PTR m_hTimer; HANDLE m_hComplete; LPTSTR m_pszWorkingText; };
/*-----------------------------------------------------------------------------
/ CPrintQueryPage / --------------------- / Constructor, creates the IPhysicalLocation object. If we are returned / a good interface pointer indicates the class is valid. / / In: / None. / / Out: / Nothing. /----------------------------------------------------------------------------*/ CPrintQueryPage::CPrintQueryPage( HWND hwnd ) : m_pPhysicalLocation( NULL ), m_pszPhysicalLocation( NULL ), m_cRef( 1 ), m_hCtrl( NULL ), m_fThreadCreated( FALSE ), m_fComplete( FALSE ), m_hwnd( hwnd ), m_hTimer( NULL ), m_fLocationEnableState( TRUE ), m_fLocationUserModified( FALSE ), m_hComplete( NULL ), m_pszWorkingText( NULL ), m_bValid( FALSE ) { TraceEnter(TRACE_FORMS, "CPrintQueryPage::CPrintQueryPage");
//
// The physical location feature can be disable using a group
// policy setting. If the feature is disabled we will just
// fail to aquire the physical location interface and continue
// operation with out pre-populating the location edit control.
//
HRESULT hr = CoCreateInstance( CLSID_PrintUIShellExtension, 0, CLSCTX_INPROC_SERVER, IID_IPhysicalLocation, (VOID**)&m_pPhysicalLocation ); if (SUCCEEDED( hr )) { //
// Check if the physical location policy is enabled.
//
if (SUCCEEDED(m_pPhysicalLocation->ShowPhysicalLocationUI())) { TimerCreate();
m_hComplete = CreateEvent( NULL, TRUE, FALSE, NULL );
if (m_hComplete) { //
// Attempt to fetch the working text from the resource file.
//
TCHAR szBuffer[MAX_PATH] = {0};
if (LoadString(GLOBAL_HINSTANCE, IDS_PRINT_WORKING_TEXT, szBuffer, ARRAYSIZE(szBuffer))) { hr = LocalAllocString (&m_pszWorkingText, szBuffer); } else { TraceAssert(FALSE); }
//
// Indicate the class is in a valid state, i.e. usable.
//
m_bValid = TRUE; } } }
TraceLeave(); }
/*-----------------------------------------------------------------------------
/ ~CPrintQueryPage / --------------------- / Destructor, release the IPhysicalLocation object and the location string. / / In: / None. / / Out: / Nothing. /----------------------------------------------------------------------------*/ CPrintQueryPage::~CPrintQueryPage() { TraceEnter(TRACE_FORMS, "CPrintQueryPage::~CPrintQueryPage");
if (m_pPhysicalLocation) { m_pPhysicalLocation->Release(); }
LocalFreeString(&m_pszPhysicalLocation);
//
// Only release the string if it was allocated and it is not the null string.
//
if (m_pszWorkingText && (m_pszWorkingText != c_szBlank)) { LocalFreeString(&m_pszWorkingText); }
TimerRelease();
if (m_hComplete) { CloseHandle( m_hComplete ); }
TraceLeave(); }
/*-----------------------------------------------------------------------------
/ AddRef / --------------------- / Increases the reference count of this object. This is method is used to / control the life time of this class when a backgroud thread is used to fetch / the physical location string. / / In: / None. / / Out: / New object refrence count. /----------------------------------------------------------------------------*/ UINT CPrintQueryPage::AddRef( VOID ) { return InterlockedIncrement(&m_cRef); }
/*-----------------------------------------------------------------------------
/ Release / --------------------- / Decreases the reference count of this object. This is method is used to / control the life time of this class when a backgroud thread is used to fetch / the physical location string. / / In: / None. / / Out: / New object refrence count. /----------------------------------------------------------------------------*/ UINT CPrintQueryPage::Release (VOID) { if (!InterlockedDecrement(&m_cRef)) { delete this; return 0; } return m_cRef; }
/*-----------------------------------------------------------------------------
/ GetSearchText / --------------------- / Returns a pointer to the current search text. The search text is the / physical location path returned from the IPhysicalLocation object. If either / the search text does not exist or not found this routine will return a / NULL string. / / In: / None. / / Out: / Ponter to the search text or the NULL string. /----------------------------------------------------------------------------*/ LPCTSTR CPrintQueryPage::GetSearchText( VOID ) { return m_pszPhysicalLocation ? m_pszPhysicalLocation : c_szBlank; }
/*-----------------------------------------------------------------------------
/ Initialize / --------------------- / Creates the background thread and calls the physical location discovery / method. / / In: / Edit control window handle where to place text when done. / bSynchronous flag TRUE use backgroud thread, FALSE call synchronously. / / Out: / HRESULT hr. /----------------------------------------------------------------------------*/ HRESULT CPrintQueryPage::Initialize( HWND hwnd, BOOL bSynchronous ) { TraceEnter(TRACE_FORMS, "CPrintQueryPage::Initialize");
HRESULT hr = S_OK; DWORD dwThreadID = 0; HANDLE hThread = NULL;
//
// If we have a valid physical location interface and the thread was not created,
// then create it now and call the discovery method.
//
if (m_bValid && !m_fThreadCreated) { //
// Bump the objects refrence count, needed for the async thread.
//
AddRef();
//
// Save the window handle in the class so the background thread
// knows what window to set the location text to.
//
m_hCtrl = hwnd;
//
// Increase this libraries object refcount, ole will not unload until
// we hit zeor and DllCanUnloadNow returns true.
//
DllAddRef();
//
// Only create the thread once.
//
m_fThreadCreated = TRUE;
//
// If we are requested to do a synchronous call then just call the
// thread proc directly.
//
if (bSynchronous) { hr = (_PhysicalLocationThread( this ) == ERROR_SUCCESS) ? S_OK : E_FAIL; } else { //
// Create the background thread.
//
hThread = CreateThread( NULL, 0, reinterpret_cast<LPTHREAD_START_ROUTINE>(CPrintQueryPage::_PhysicalLocationThread), reinterpret_cast<LPVOID>( this ), 0, &dwThreadID);
TraceAssert(hThread);
//
// If the thread failed creation clean up the dll refrence count
// and the object refrence and the thread created flag.
//
if (!hThread) { m_fThreadCreated = FALSE; DllRelease(); Release(); hr = E_FAIL; } else { //
// Thread is running just close the handle, we let the thread die
// on its own normally.
//
CloseHandle(hThread);
//
// Indicate the request is pending.
//
hr = HRESULT_FROM_WIN32 (ERROR_IO_PENDING); } } }
//
// If we have a valid interface pointer and the background thread
// has not completed then indicated the data is still pending.
//
else if(m_bValid && !m_fComplete) { //
// Indicate the request is pending.
//
hr = HRESULT_FROM_WIN32 (ERROR_IO_PENDING); }
//
// If we failed with IO_PENDING then set the working text.
//
if (FAILED(hr) && HRESULT_CODE(hr) == ERROR_IO_PENDING) { //
// Set the new location text.
//
SetLocationText (hwnd, m_pszWorkingText, TRUE, TRUE); PostMessage (m_hCtrl, EM_SETSEL, 0, 0); }
TraceLeaveResult(hr); }
/*-----------------------------------------------------------------------------
/ _PhysicalLocationThread / --------------------- / This routine is the backgroud thread thunk. It accepts the CPrintQueryPage / this pointer and then calles the actual discovery method. The purpose of / this routine is simple to capture the this pointer after the thread was / created and then invoke a method. / / In: / Pointer to PrintQueryPage class. / / Out: / TRUE success, FALSE error occurred. /----------------------------------------------------------------------------*/ DWORD WINAPI CPrintQueryPage::_PhysicalLocationThread( PVOID pVoid ) { DWORD dwRetval = ERROR_OUTOFMEMORY;
if ( SUCCEEDED(CoInitialize(NULL)) ) { //
// Get a pointer to this class.
//
CPrintQueryPage *pPrintQueryPage = reinterpret_cast<CPrintQueryPage *>( pVoid );
//
// Invoke the location discovery process.
//
dwRetval = pPrintQueryPage->Discovery();
//
// Set the completion event, in case someone is waiting.
//
SetEvent(pPrintQueryPage->m_hComplete);
//
// Indicate the discovery process completed.
//
pPrintQueryPage->m_fComplete = TRUE;
//
// Release the timer
//
pPrintQueryPage->TimerRelease();
//
// Release the refrence to the PrintQueryPage class.
//
pPrintQueryPage->Release();
//
// COM no longer needed
//
CoUninitialize(); }
DllRelease(); return dwRetval; }
/*-----------------------------------------------------------------------------
/ Discovery / --------- / This routine is the backgroud thread discovery process. Since the act / of figuring out the physical location of this machin must hit the net / it can take a significant amount of time. Hence we do this in a separate / thread. / / In: / Nothing. / / Out: / TRUE success, FALSE error occurred. /----------------------------------------------------------------------------*/ DWORD CPrintQueryPage::Discovery( VOID ) { TraceEnter(TRACE_FORMS, "CPrintQueryPage::Discovery");
//
// Start the discovery process for finding the physical location search text
// for this machine.
//
HRESULT hr = m_pPhysicalLocation->DiscoverPhysicalLocation();
if (SUCCEEDED( hr )) { BSTR pbsPhysicalLocation = NULL;
//
// Get the physical location search text.
//
hr = m_pPhysicalLocation->GetSearchPhysicalLocation( &pbsPhysicalLocation );
//
// If the error indicates the length was returned then allocate the text buffer.
//
if (SUCCEEDED( hr ) && pbsPhysicalLocation) { //
// Release the previous string if any.
//
if (m_pszPhysicalLocation) { LocalFreeString(&m_pszPhysicalLocation); }
//
// Convert the BSTR location string to a TSTR string.
//
hr = LocalAllocStringW2T( &m_pszPhysicalLocation, pbsPhysicalLocation ); }
//
// Release the physical location string if it was allocated.
//
if( pbsPhysicalLocation ) { SysFreeString( pbsPhysicalLocation ); } }
//
// Set the new location text.
//
SetLocationText( m_hCtrl, GetSearchText(), FALSE, FALSE );
TraceLeaveValue(SUCCEEDED( hr ) ? ERROR_SUCCESS : ERROR_OUTOFMEMORY); }
/*-----------------------------------------------------------------------------
/ WaitForLocation / --------------------- / Wait for the printer location information. / / In: / hwnd parent window handle. / / Out: / BOOL TRUE if success, FALSE if error. /----------------------------------------------------------------------------*/ VOID CPrintQueryPage::WaitForLocation( HWND hwnd ) { TraceEnter(TRACE_FORMS, "CPrintQueryPage::WaitForLocation");
//
// Only wait if we have a valid location interface pointer and
// completion event handle was created and the thread is running.
//
if (m_bValid && m_hComplete && m_fThreadCreated) { //
// Keep waiting until the physical location is avaialble or a timeout.
//
for (BOOL fExit = FALSE; !fExit; ) { switch (MsgWaitForMultipleObjects(1, &m_hComplete, FALSE, MAX_LOCATION_MSG_WAIT_TIME, QS_ALLINPUT)) { case WAIT_OBJECT_0: fExit = TRUE; break;
case WAIT_TIMEOUT: fExit = TRUE; break;
default: { //
// Process any message now.
//
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } break; } } } }
TraceLeave(); }
/*-----------------------------------------------------------------------------
/ TimerCreate / --------------------- / Create the timer event to detect if the discovery method is taking too long. / / In: / / Out: /----------------------------------------------------------------------------*/ VOID CPrintQueryPage::TimerCreate( VOID ) { TraceEnter(TRACE_FORMS, "CPrintQueryPage::TimerCreate");
if (!m_hTimer) { m_hTimer = SetTimer(m_hwnd, WM_USER, MAX_LOCATION_WAIT_TIME, NULL); }
TraceLeave(); }
/*-----------------------------------------------------------------------------
/ TimerRelease / --------------------- / Release the timer event. / / In: / / Out: /----------------------------------------------------------------------------*/ VOID CPrintQueryPage::TimerRelease( VOID ) { TraceEnter(TRACE_FORMS, "CPrintQueryPage::TimerRelease");
if (m_hTimer) { KillTimer(m_hwnd, m_hTimer); m_hTimer = NULL; }
TraceLeave(); }
/*-----------------------------------------------------------------------------
/ TimerExpire / --------------------- / / In: / / Out: /----------------------------------------------------------------------------*/ VOID CPrintQueryPage::TimerExpire( VOID ) { TraceEnter(TRACE_FORMS, "CPrintQueryPage::TimerExpire");
//
// The search data is not complete
//
if (!m_fComplete) { //
// Blank out the location text, it took too long to find.
//
SetLocationText(m_hCtrl, c_szBlank, FALSE, TRUE);
//
// Set the completion event, in case someone is waiting.
//
SetEvent(m_hComplete);
//
// Indicate the discovery process completed.
//
m_fComplete = TRUE; }
//
// Release the timer, the time is a one shot notification.
//
TimerRelease();
TraceLeave(); }
/*-----------------------------------------------------------------------------
/ EnableLocationEditText / --------------------- / Enabled or disable the location edit text only if it is does not contain / the pending text. / / In: / hwnd parent window handle. / / Out: / BOOL TRUE if success, FALSE if error. /----------------------------------------------------------------------------*/ VOID CPrintQueryPage::EnableLocationEditText( HWND hwnd, BOOL bEnable ) { TraceEnter(TRACE_FORMS, "CPrintQueryPage::EnableLocationEditText");
HWND hCtrl = GetDlgItem(hwnd, IDC_PRINTLOCATION); HWND hBrowseCtrl = GetDlgItem(hwnd, IDC_PRINTBROWSE);
//
// If the CPrintQueryPage is valid then handle the location
// edit control differently.
//
if (m_bValid) { TCHAR szBuffer[MAX_LOCATION] = {0};
//
// Save the previous location enable state.
//
m_fLocationEnableState = bEnable;
//
// Get the current location text.
//
GetWindowText(hCtrl, szBuffer, ARRAYSIZE(szBuffer));
//
// Do not change the location edit control enable state when the
// working text is there. The reason for this is the text
// is hard to read when the control is disabled, but when the
// control is just read only the text is black not gray hence
// eaiser to read.
//
if (!_tcscmp(szBuffer, m_pszWorkingText)) { //
// For an unknown reason the control with the location
// text has the input focus, the default input focus
// should be on the printer name therefore I will
// set the focus here.
//
SetFocus(GetDlgItem(hwnd, IDC_PRINTNAME)); } else { EnableWindow(hBrowseCtrl, bEnable); EnableWindow(hCtrl, bEnable); } } else { EnableWindow(hBrowseCtrl, bEnable); EnableWindow(hCtrl, bEnable); }
TraceLeave(); }
/*-----------------------------------------------------------------------------
/ LocationEditTextChanged / --------------------- / / In: / hwnd parent window handle. / / Out: / BOOL TRUE if success, FALSE if error. /----------------------------------------------------------------------------*/ VOID CPrintQueryPage::LocationEditTextChanged( HWND hwnd ) { TraceEnter(TRACE_FORMS, "CPrintQueryPage::LocationEditTextChanged");
//
// The search data is complete
//
if (m_fComplete) { m_fLocationUserModified = TRUE; }
TraceLeave(); }
/*-----------------------------------------------------------------------------
/ PersistLocation / --------------------- / / In: / hwnd parent window handle. / / Out: / BOOL TRUE if success, FALSE if error. /----------------------------------------------------------------------------*/ HRESULT CPrintQueryPage::PersistLocation(HWND hwnd, IPersistQuery* pPersistQuery, BOOL fRead) { TraceEnter(TRACE_FORMS, "CPrintQueryPage::PersistLocation");
HRESULT hr = S_OK; TCHAR szBuffer[MAX_LOCATION] = {0};
//
// Get the control handle for the location edit control
//
HWND hCtrl = GetDlgItem(hwnd, IDC_PRINTLOCATION);
//
// Are we to read the persisted query string.
//
if (fRead) { //
// Read the persisted location string.
//
hr = pPersistQuery->ReadString( c_szMsPrintersMore, c_szLocationTag, szBuffer, ARRAYSIZE( szBuffer ) ); FailGracefully(hr, "Failed to read location state");
//
// Assume this is the exact string.
//
LPCTSTR pLocation = szBuffer;
//
// If the dynamic sentinal was found then wait for the dynamic location
// text to be avaiable.
//
if (!_tcscmp(szBuffer, c_szDynamicTag)) { WaitForLocation(hwnd); pLocation = GetSearchText(); }
//
// Set the persisted location string in the query form.
//
SetLocationText(hCtrl, pLocation, FALSE, TRUE); } else { //
// If the user modified the location text then save this text, otherwize
// save a sentinal string which indicates we are to determine the location
// dynamically when the persisted query is read back.
//
if (m_fLocationUserModified) { GetWindowText(hCtrl, szBuffer, ARRAYSIZE(szBuffer)); hr = pPersistQuery->WriteString( c_szMsPrintersMore, c_szLocationTag, szBuffer ); FailGracefully(hr, "Failed to write location state"); } else { hr = pPersistQuery->WriteString( c_szMsPrintersMore, c_szLocationTag, c_szDynamicTag ); FailGracefully(hr, "Failed to write location working state"); } }
exit_gracefully:
TraceLeaveResult(hr); }
/*-----------------------------------------------------------------------------
/ SetLocationText / --------------------- / / In: / hwnd parent window handle. / / Out: / BOOL TRUE if success, FALSE if error. /----------------------------------------------------------------------------*/ VOID CPrintQueryPage::SetLocationText( HWND hCtrl, LPCTSTR pszString, BOOL fReadOnly, BOOL fIgnoreWorkingText ) { TraceEnter(TRACE_FORMS, "CPrintQueryPage::SetLocationText");
if (IsWindow(hCtrl)) { //
// Is the CPrintQueryPage in a valid state.
//
if (m_bValid) { TCHAR szBuffer[MAX_LOCATION];
//
// Read the current location text.
//
GetWindowText(hCtrl, szBuffer, ARRAYSIZE(szBuffer));
//
// Stick the location string in the edit control if it contains working.
//
if (!_tcscmp(szBuffer, m_pszWorkingText) || fIgnoreWorkingText) { SetWindowText(hCtrl, pszString); }
//
// Reset the control to non read only state.
//
SendMessage(hCtrl, EM_SETREADONLY, fReadOnly, 0);
//
// Enable the control if the read only is disabled.
//
if (!fReadOnly) { //
// Enable the edit control.
//
EnableWindow(hCtrl, m_fLocationEnableState); }
//
// Only enable the browse button when we have a location string
// and the then control is not in read only mode.
//
EnableWindow(GetDlgItem(m_hwnd, IDC_PRINTBROWSE), !fReadOnly && m_fLocationEnableState); } else { //
// If we are not using the location interface, just set the location text.
//
SetWindowText(hCtrl, pszString); } }
TraceLeave(); }
/*-----------------------------------------------------------------------------
/ BrowseForLocation / --------------------- / Starts the browse for location tree view and populates the edit control / with a valid selection. / / In: / hwnd parent window handle. / / Out: / Nothing. /----------------------------------------------------------------------------*/ VOID CPrintQueryPage::BrowseForLocation( HWND hwnd ) { TraceEnter(TRACE_FORMS, "CPrintQueryPage::BrowseForLocation");
if (m_bValid) { BSTR pbPhysicalLocation = NULL; BSTR pbDefaultLocation = NULL; LPTSTR pszPhysicalLocation = NULL; HRESULT hr = E_FAIL; TCHAR szText[MAX_LOCATION]= {0};
//
// Convert the physical location to a BSTR for the IPhysicalLocation
// object can pre-expand the browse tree.
//
if (GetWindowText(GetDlgItem(hwnd, IDC_PRINTLOCATION), szText, ARRAYSIZE(szText))) { pbDefaultLocation = T2BSTR(szText); } else { pbDefaultLocation = T2BSTR(m_pszPhysicalLocation); }
//
// Display the location tree.
//
hr = m_pPhysicalLocation->BrowseForLocation(hwnd, pbDefaultLocation, &pbPhysicalLocation);
if(SUCCEEDED(hr) && pbPhysicalLocation) { //
// Convert the BSTR location string to a TSTR string.
//
hr = LocalAllocStringW2T(&pszPhysicalLocation, pbPhysicalLocation);
if(SUCCEEDED(hr)) { //
// Set the location text.
//
SetLocationText(m_hCtrl, pszPhysicalLocation, FALSE, TRUE); }
//
// Release the TCHAR physical location string.
//
LocalFreeString(&pszPhysicalLocation);
//
// Release the physical location string.
//
SysFreeString(pbPhysicalLocation); }
//
// Release the default locatin string.
//
SysFreeString(pbDefaultLocation); }
TraceLeave(); }
/*-----------------------------------------------------------------------------
/ OnInitDialog / --------------------- / Set the UI's initial state, on down level machines the browse button is / removed and the edit control is stetched to match the size of the other / edit controls, i.e. name, model. / / In: / hwnd parent window handle. / / Out: / Nothing. /----------------------------------------------------------------------------*/ VOID CPrintQueryPage::OnInitDialog( HWND hwnd ) { TraceEnter(TRACE_FORMS, "CPrintQueryPage::OnInitDialog");
if (!m_bValid) { //
// If the IPhysicalLocation interface is not available, hide the browse
// button and extend the location edit control appropriately
//
RECT rcName = {0}; RECT rcLocation = {0};
GetWindowRect (GetDlgItem (hwnd, IDC_PRINTNAME), &rcName);
GetWindowRect (GetDlgItem (hwnd, IDC_PRINTLOCATION), &rcLocation);
SetWindowPos (GetDlgItem (hwnd, IDC_PRINTLOCATION), NULL, 0,0, rcName.right - rcName.left, rcLocation.bottom - rcLocation.top, SWP_NOMOVE|SWP_NOZORDER);
ShowWindow (GetDlgItem (hwnd, IDC_PRINTBROWSE), SW_HIDE); }
TraceLeave(); }
/*-----------------------------------------------------------------------------
/ PopulateLocationEditText / --------------------- / Populates the location edit control with the default location of this / machine. / / In: / hwnd parent window handle. / / Out: / BOOL TRUE if success, FALSE if error. /----------------------------------------------------------------------------*/ BOOL PopulateLocationEditText( HWND hwnd, BOOL bClearField ) { TraceEnter(TRACE_FORMS, "PopulateLocationEditText");
CPrintQueryPage *pPrintQueryPage = reinterpret_cast<CPrintQueryPage *>(GetWindowLongPtr(hwnd, DWLP_USER));
if (pPrintQueryPage) { HWND hCtrl = GetDlgItem(hwnd, IDC_PRINTLOCATION);
HRESULT hr = pPrintQueryPage->Initialize( hCtrl, FALSE );
if (SUCCEEDED( hr )) { if( bClearField ) { SetWindowText( hCtrl, c_szBlank); } else { SetWindowText( hCtrl, pPrintQueryPage->GetSearchText( )); } } }
TraceLeaveValue(TRUE); }
/*-----------------------------------------------------------------------------
/ bEnumForms / ---------- / Enumerates the forms on the printer identified by the handle. / / In: / IN HANDLE hPrinter, / IN DWORD dwLevel, / IN PBYTE *ppBuff, / IN PDWORD pcReturned / / Out: / Pointer to forms array and count of forms in the array if / success, NULL ponter and zero number of forms if failure. / BOOL TRUE if success, FALSE if error. /----------------------------------------------------------------------------*/ BOOL bEnumForms( IN HANDLE hPrinter, IN DWORD dwLevel, IN PFORM_INFO_1 *ppFormInfo, IN PDWORD pcReturned ) { BOOL bReturn = FALSE; DWORD dwReturned = 0; DWORD dwNeeded = 0; PBYTE p = NULL; BOOL bStatus = FALSE;
//
// Get buffer size for enum forms.
//
bStatus = EnumForms( hPrinter, dwLevel, NULL, 0, &dwNeeded, &dwReturned );
//
// Check if the function returned the buffer size.
//
if( GetLastError() != ERROR_INSUFFICIENT_BUFFER ) { goto Cleanup; }
//
// If buffer allocation fails.
//
p = (PBYTE)LocalAlloc( LPTR, dwNeeded );
if( p == NULL ) { goto Cleanup; }
//
// Get the forms enumeration
//
bStatus = EnumForms( hPrinter, dwLevel, p, dwNeeded, &dwNeeded, &dwReturned );
//
// Copy back the buffer pointer and count.
//
if( bStatus ) { bReturn = TRUE; *ppFormInfo = (PFORM_INFO_1)p; *pcReturned = dwReturned; }
Cleanup:
if( bReturn == FALSE ) { //
// Indicate failure.
//
*ppFormInfo = NULL; *pcReturned = 0;
//
// Release any allocated memory.
//
if ( p ) { LocalFree( p ); } }
return bReturn; }
/*-----------------------------------------------------------------------------
/ PopulatePrintPageSize / ---------------- / Eumerates all the pages size from this machine's print spooler. This allows / a user to choose from a list of available forms rather than remembering the / name of the particular form. / / In: / hwnd parent window handle. / / Out: / BOOL TRUE if success, FALSE if error. /----------------------------------------------------------------------------*/ BOOL PopulatePrintPageSize( HWND hwnd ) { HANDLE hServer = NULL; PFORM_INFO_1 pFormInfo = NULL; DWORD FormCount = 0; BOOL bRetval = FALSE; TCHAR szBuffer[MAX_PATH];
//
// Open the local print server with default access.
//
BOOL bStatus = OpenPrinter( NULL, &hServer, NULL );
if( bStatus ) { //
// Enumerate the forms.
//
bStatus = bEnumForms( hServer, 1, &pFormInfo, &FormCount ); }
if( bStatus && pFormInfo ) { //
// Fill the combo box.
//
for( UINT i = 0; i < FormCount; i++ ) { ComboBox_AddString( GetDlgItem( hwnd, IDC_PRINTPAGESIZE ), pFormInfo[i].pName ); }
//
// Set the limit text in the form name edit control
//
ComboBox_LimitText( GetDlgItem( hwnd, IDC_PRINTPAGESIZE ), CCHFORMNAME-1 );
//
// Return success.
//
bRetval = TRUE; }
if( pFormInfo ) { //
// Release the forms buffer if it was allocated.
//
LocalFree( pFormInfo ); }
if ( hServer ) { ClosePrinter(hServer); }
return bRetval; }
/*-----------------------------------------------------------------------------
/ PopulatePrintSpeed / ---------------- / Set the print speed up down arrow control with an upper and lower / bound range. / / In: / hwnd parent window handle / / Out: / BOOL TRUE if success, FALSE if error. /----------------------------------------------------------------------------*/ BOOL PopulatePrintSpeed( HWND hwnd ) { //
// Set the print speed up down arrow range.
//
SendMessage( GetDlgItem( hwnd, IDC_PRINTSPEED_UPDN ), UDM_SETRANGE, 0, MAKELPARAM( 9999, 1 ) ); Edit_LimitText(GetDlgItem(hwnd, IDC_PRINTSPEED), 4); return TRUE; }
/*-----------------------------------------------------------------------------
/ PopulateResolution / ---------------- / Fill the print resolution contrl with valid resolution information. / / In: / hwnd / / Out: / BOOL TRUE if success, FALSE if error. /----------------------------------------------------------------------------*/ BOOL PopulatePrintResolution( HWND hwnd ) { TCHAR szBuffer[MAX_PATH];
//
// Fill in the print resolution combo-box.
//
for( INT i = 0; i < ARRAYSIZE( Resolutions ); i++ ) { if( !LoadString(GLOBAL_HINSTANCE, Resolutions[i].idString, szBuffer, ARRAYSIZE(szBuffer))) { TraceAssert(FALSE); } ComboBox_AddString( GetDlgItem( hwnd, IDC_PRINTRES ), szBuffer ); }
return TRUE; }
/*-----------------------------------------------------------------------------
/ GetPrinterMoreParameters. / ---------------- / Build the query string from the controls on the printer more page. / / In: / hwnd parent window handle. / pLen pointer to length of query string. / pszBuffer pointer to buffer where to return the query string. / / Out: / Nothing. /----------------------------------------------------------------------------*/ VOID GetPrinterMoreParameters( HWND hwnd, UINT *puLen, LPWSTR pszBuffer ) { USES_CONVERSION; TCHAR szScratch[MAX_PATH] = {0}; TCHAR szText[MAX_PATH] = {0}; INT i = 0;
//
// Read the check box states and build the query string.
//
if( Button_GetCheck( GetDlgItem( hwnd, IDC_PRINTDUPLEX ) ) == BST_CHECKED ) PutStringElementW(pszBuffer, puLen, c_szPrintDuplex);
if( Button_GetCheck( GetDlgItem( hwnd, IDC_PRINTCOLOR ) ) == BST_CHECKED ) PutStringElementW(pszBuffer, puLen, c_szPrintColor);
if( Button_GetCheck( GetDlgItem( hwnd, IDC_PRINTSTAPLE ) ) == BST_CHECKED ) PutStringElementW(pszBuffer, puLen, c_szPrintStapling);
//
// Read the paper size setting.
//
ComboBox_GetText( GetDlgItem( hwnd, IDC_PRINTPAGESIZE ), szText, ARRAYSIZE( szText ) );
if( lstrlen( szText ) ) { wsprintf( szScratch, c_szPrintPaperSize, szText ); PutStringElementW(pszBuffer, puLen, T2W(szScratch)); }
//
// Read the printer resolution setting
//
i = ComboBox_GetCurSel( GetDlgItem( hwnd, IDC_PRINTRES ) );
if( i > 0 && i < ARRAYSIZE( Resolutions ) ) { wsprintf( szScratch, c_szPrintResolution, Resolutions[i].szString ); PutStringElementW(pszBuffer, puLen, T2W(szScratch)); }
//
// Read the printer speed setting
//
i = (LONG)SendMessage( GetDlgItem( hwnd, IDC_PRINTSPEED_UPDN ), UDM_GETPOS, 0, 0 );
if( LOWORD(i) > 1 && i != -1 ) { wsprintf( szScratch, c_szPrintSpeed, i ); PutStringElementW(pszBuffer, puLen, T2W(szScratch)); } }
/*-----------------------------------------------------------------------------
/ GetPrinterLocationParameter. / ---------------- / Build the query string from the location control on the printer page. / / In: / hwnd parent window handle. / pLen pointer to length of query string. / pszBuffer pointer to buffer where to return the query string. / / Out: / Nothing. /----------------------------------------------------------------------------*/ VOID GetPrinterLocationParameter( HWND hwnd, UINT *puLen, LPWSTR pszBuffer ) { USES_CONVERSION; TCHAR szScratch[MAX_PATH*2] = {0}; TCHAR szText[MAX_PATH] = {0}; TCHAR szWorkingText[MAX_PATH] = {0}; DWORD dwLocationLength = 0;
HWND hCtrl = GetDlgItem(hwnd, IDC_PRINTLOCATION);
if ( hCtrl != NULL ) { dwLocationLength = GetWindowText(hCtrl, szText, ARRAYSIZE(szText)); if (dwLocationLength != 0) { if (LoadString(GLOBAL_HINSTANCE, IDS_PRINT_WORKING_TEXT, szWorkingText, ARRAYSIZE(szWorkingText))) { if (_tcscmp(szText, szWorkingText)) { BOOL fUseMoreComplexSearch = FALSE;
//
// If we have a location that ends in a forward slash,
// we'll trim that off and use a slightly more complex
// search parameter so that we can pick up locations
// that either match the location parameter exactly or
// start with the parameter and have a slash immediately
// following.
//
if ( dwLocationLength > 1 ) { if ( szText[dwLocationLength-1] == TEXT('/') ) { szText[dwLocationLength-1] = TEXT('\0'); fUseMoreComplexSearch = TRUE; } } if ( fUseMoreComplexSearch ) { wsprintf(szScratch, c_szLocationQueryComplex, szText, szText); } else { wsprintf(szScratch, c_szLocationQuery, szText); }
PutStringElementW(pszBuffer, puLen, T2W(szScratch)); } else { //
// We are not going to wait the location field if the search process
// has been kicked off. Just hit the expire timer to cancel the location
// thread. This will ensure that the result list and the query params
// will be consistent.
//
CPrintQueryPage *pPrintQueryPage = reinterpret_cast<CPrintQueryPage *>(GetWindowLongPtr(hwnd, DWLP_USER)); if (pPrintQueryPage) { pPrintQueryPage->TimerExpire(); } } } else { TraceAssert(FALSE); } } } else { // GetDlgItem() returned NULL for the location control.
TraceAssert(FALSE); } }
/*-----------------------------------------------------------------------------
/ Query Page: Printers /----------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------
/ PageProc_Printer / ---------------- / PageProc for handling the messages for this object. / / In: / pPage -> instance data for this form / hwnd = window handle for the form dialog / uMsg, wParam, lParam = message parameters / / Out: / HRESULT (E_NOTIMPL) if not handled /----------------------------------------------------------------------------*/ HRESULT CALLBACK PageProc_Printers(LPCQPAGE pPage, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { HRESULT hr = S_OK; LPWSTR pQuery = NULL; UINT uLen = 0;
TraceEnter(TRACE_FORMS, "PageProc_Printers");
switch ( uMsg ) { case CQPM_INITIALIZE: case CQPM_RELEASE: break;
case CQPM_ENABLE: { CPrintQueryPage *pPrintQueryPage = reinterpret_cast<CPrintQueryPage *>(GetWindowLongPtr(hwnd, DWLP_USER));
if (pPrintQueryPage) { pPrintQueryPage->EnableLocationEditText( hwnd, (BOOL)wParam ); }
// Enable the form controls,
EnablePageControls(hwnd, ctrls1, ARRAYSIZE(ctrls1), (BOOL)wParam); break; }
case CQPM_GETPARAMETERS: { //
// Get the printer name and model paramters.
//
hr = GetQueryString(&pQuery, c_szQueryPrefix, hwnd, ctrls1, ARRAYSIZE(ctrls1));
if ( SUCCEEDED(hr) ) { hr = QueryParamsAlloc((LPDSQUERYPARAMS*)lParam, pQuery, GLOBAL_HINSTANCE, ARRAYSIZE(columns), columns); LocalFreeStringW(&pQuery); }
//
// Get the location parameter.
//
GetPrinterLocationParameter( hwnd, &uLen, NULL );
if (uLen) { hr = LocalAllocStringLenW(&pQuery, uLen);
if ( SUCCEEDED(hr) ) { GetPrinterLocationParameter( hwnd, &uLen, pQuery ); hr = QueryParamsAddQueryString((LPDSQUERYPARAMS*)lParam, pQuery ); LocalFreeStringW(&pQuery); } }
FailGracefully(hr, "PageProc_Printers: Failed to build DS argument block");
break; }
case CQPM_CLEARFORM: { // Reset the form controls.
PopulateLocationEditText( hwnd, TRUE ); ResetPageControls(hwnd, ctrls1, ARRAYSIZE(ctrls1)); break; }
case CQPM_PERSIST: { BOOL fRead = (BOOL)wParam; IPersistQuery* pPersistQuery = (IPersistQuery*)lParam;
CPrintQueryPage *pPrintQueryPage = reinterpret_cast<CPrintQueryPage *>(GetWindowLongPtr(hwnd, DWLP_USER));
if (pPrintQueryPage) { hr = pPrintQueryPage->PersistLocation(hwnd, pPersistQuery, fRead); }
if (SUCCEEDED(hr)) { // Read the standard controls from the page,
hr = PersistQuery(pPersistQuery, fRead, c_szMsPrinters, hwnd, ctrls1, ARRAYSIZE(ctrls1)); } FailGracefully(hr, "Failed to persist page"); break; }
case CQPM_SETDEFAULTPARAMETERS: { //
// so that the caller can pass parameters to the form we support an IPropertyBag in the
// OPENQUERYWINDOW structure. If wParam == TRUE, and lParam is non-zero then we
// assume we should decode this structure to get the information we need from it.
//
if ( wParam && lParam ) { OPENQUERYWINDOW *poqw = (OPENQUERYWINDOW*)lParam; if ( poqw->dwFlags & OQWF_PARAMISPROPERTYBAG ) { IPropertyBag *ppb = poqw->ppbFormParameters; SetDlgItemFromProperty(ppb, L"printName", hwnd, IDC_PRINTNAME, NULL); SetDlgItemFromProperty(ppb, L"printLocation", hwnd, IDC_PRINTLOCATION, NULL); SetDlgItemFromProperty(ppb, L"printModel", hwnd, IDC_PRINTMODEL, NULL); } }
break; }
case CQPM_HELP: { LPHELPINFO pHelpInfo = (LPHELPINFO)lParam; WinHelp((HWND)pHelpInfo->hItemHandle, DSQUERY_HELPFILE, HELP_WM_HELP, (DWORD_PTR)aFormHelpIDs); break; }
case DSQPM_GETCLASSLIST: { hr = ClassListAlloc((LPDSQUERYCLASSLIST*)lParam, c_szClassList, ARRAYSIZE(c_szClassList)); FailGracefully(hr, "Failed to allocate class list"); break; }
case DSQPM_HELPTOPICS: { HWND hwndFrame = (HWND)lParam; TraceMsg("About to display help topics for find printers - ocm.chm"); HtmlHelp(hwndFrame, TEXT("omc.chm"), HH_HELP_FINDER, 0); break; }
default: hr = E_NOTIMPL; break; }
exit_gracefully:
TraceLeaveResult(hr); }
/*-----------------------------------------------------------------------------
/ DlgProc_Printers / ---------------- / Standard dialog proc for the form, handle any special buttons and other / such nastyness we must here. / / In: / hwnd, uMsg, wParam, lParam = standard parameters / / Out: / BOOL /----------------------------------------------------------------------------*/ INT_PTR CALLBACK DlgProc_Printers(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { INT_PTR fResult = TRUE;
CPrintQueryPage *pPrintQueryPage = reinterpret_cast<CPrintQueryPage *>(GetWindowLongPtr(hwnd, DWLP_USER));
switch ( uMsg ) { case WM_INITDIALOG: { Edit_LimitText(GetDlgItem(hwnd, IDC_PRINTNAME), MAX_PATH-1); Edit_LimitText(GetDlgItem(hwnd, IDC_PRINTLOCATION), MAX_LOCATION-1); Edit_LimitText(GetDlgItem(hwnd, IDC_PRINTMODEL), MAX_PATH-1);
pPrintQueryPage = new CPrintQueryPage(hwnd);
if (pPrintQueryPage) { SetWindowLongPtr(hwnd, DWLP_USER, reinterpret_cast<LONG_PTR>(pPrintQueryPage)); pPrintQueryPage->OnInitDialog(hwnd); PopulateLocationEditText(hwnd, FALSE); } else { fResult = FALSE; } break; }
case WM_CONTEXTMENU: { WinHelp((HWND)wParam, DSQUERY_HELPFILE, HELP_CONTEXTMENU, (DWORD_PTR)aFormHelpIDs); break; }
case WM_NCDESTROY: { if (pPrintQueryPage) { pPrintQueryPage->Release(); } SetWindowLongPtr(hwnd, DWLP_USER, NULL); break; }
case WM_TIMER: { if (pPrintQueryPage) { pPrintQueryPage->TimerExpire(); } break; }
case WM_COMMAND: { if((GET_WM_COMMAND_CMD(wParam, lParam) == EN_CHANGE) && (GET_WM_COMMAND_ID(wParam, lParam) == IDC_PRINTLOCATION)) { if (pPrintQueryPage) { pPrintQueryPage->LocationEditTextChanged(hwnd); } } else if((GET_WM_COMMAND_ID(wParam, lParam) == IDC_PRINTBROWSE)) { if (pPrintQueryPage) { pPrintQueryPage->BrowseForLocation(hwnd); } } else { fResult = FALSE; } break; }
default: { fResult = FALSE; break; } }
return fResult; }
/*-----------------------------------------------------------------------------
/ PageProc_PrintersMore / --------------------- / PageProc for handling the messages for this object. / / In: / pPage -> instance data for this form / hwnd = window handle for the form dialog / uMsg, wParam, lParam = message parameters / / Out: / HRESULT (E_NOTIMPL) if not handled /----------------------------------------------------------------------------*/ HRESULT CALLBACK PageProc_PrintersMore(LPCQPAGE pPage, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { HRESULT hr = S_OK;
TraceEnter(TRACE_FORMS, "PageProc_PrintersMore");
switch ( uMsg ) { case CQPM_INITIALIZE: case CQPM_RELEASE: break;
case CQPM_ENABLE: EnableWindow( GetDlgItem( hwnd, IDC_PRINTPAGESIZE ), (BOOL)wParam ); EnableWindow( GetDlgItem( hwnd, IDC_PRINTRES ), (BOOL)wParam ); EnableWindow( GetDlgItem( hwnd, IDC_PRINTSPEED ), (BOOL)wParam ); EnableWindow( GetDlgItem( hwnd, IDC_PRINTSPEED_UPDN ), (BOOL)wParam ); EnableWindow( GetDlgItem( hwnd, IDC_PRINTDUPLEX ), (BOOL)wParam ); EnableWindow( GetDlgItem( hwnd, IDC_PRINTCOLOR ), (BOOL)wParam ); EnableWindow( GetDlgItem( hwnd, IDC_PRINTSTAPLE ), (BOOL)wParam ); break;
case CQPM_GETPARAMETERS: { LPWSTR pszBuffer = NULL; UINT uLen = 0;
// Format the parameters for the 2nd page of the query form, this builds
// an LDAP string and then appends it to the string we have in the
// existing query parameter block.
GetPrinterMoreParameters( hwnd, &uLen, NULL );
if ( uLen ) { hr = LocalAllocStringLenW(&pszBuffer, uLen);
if ( SUCCEEDED(hr) ) { GetPrinterMoreParameters( hwnd, &uLen, pszBuffer ); hr = QueryParamsAddQueryString((LPDSQUERYPARAMS*)lParam, pszBuffer ); LocalFreeStringW(&pszBuffer); }
FailGracefully(hr, "PageProc_PrintersMore: Failed to build DS argument block"); }
break; }
case CQPM_CLEARFORM: SetDlgItemText( hwnd, IDC_PRINTPAGESIZE, TEXT("") ); ComboBox_SetCurSel( GetDlgItem( hwnd, IDC_PRINTRES ), 0 ); SendMessage( GetDlgItem( hwnd, IDC_PRINTSPEED_UPDN ), UDM_SETPOS, 0, MAKELPARAM( 1, 0 ) ); Button_SetCheck( GetDlgItem( hwnd, IDC_PRINTDUPLEX ), BST_UNCHECKED ); Button_SetCheck( GetDlgItem( hwnd, IDC_PRINTCOLOR ), BST_UNCHECKED ); Button_SetCheck( GetDlgItem( hwnd, IDC_PRINTSTAPLE ), BST_UNCHECKED ); break;
case CQPM_PERSIST: { IPersistQuery* pPersistQuery = (IPersistQuery*)lParam; BOOL fRead = (BOOL)wParam; INT i = 0; TCHAR szBuffer[MAX_PATH];
if ( fRead ) { hr = pPersistQuery->ReadInt( c_szMsPrintersMore, c_szColor, &i ); FailGracefully(hr, "Failed to read color state"); Button_SetCheck( GetDlgItem( hwnd, IDC_PRINTCOLOR ), i ? BST_CHECKED : BST_UNCHECKED );
hr = pPersistQuery->ReadInt( c_szMsPrintersMore, c_szDuplex, &i ); FailGracefully(hr, "Failed to read duplex state"); Button_SetCheck( GetDlgItem( hwnd, IDC_PRINTDUPLEX ), i ? BST_CHECKED : BST_UNCHECKED );
hr = pPersistQuery->ReadInt( c_szMsPrintersMore, c_szStaple, &i ); FailGracefully(hr, "Failed to read staple state"); Button_SetCheck( GetDlgItem( hwnd, IDC_PRINTSTAPLE ), i ? BST_CHECKED : BST_UNCHECKED );
hr = pPersistQuery->ReadInt( c_szMsPrintersMore, c_szResolution, &i ); FailGracefully(hr, "Failed to read resolution state"); ComboBox_SetCurSel( GetDlgItem( hwnd, IDC_PRINTRES ), i );
hr = pPersistQuery->ReadInt( c_szMsPrintersMore, c_szSpeed, &i ); FailGracefully(hr, "Failed to read speed state"); SendMessage( GetDlgItem( hwnd, IDC_PRINTSPEED_UPDN ), UDM_SETPOS, 0, MAKELPARAM( i, 0 ) );
hr = pPersistQuery->ReadString( c_szMsPrintersMore, c_szPaperSize, szBuffer, ARRAYSIZE( szBuffer ) ); FailGracefully(hr, "Failed to read paper size state"); ComboBox_SetText( GetDlgItem( hwnd, IDC_PRINTPAGESIZE ), szBuffer );
} else { i = Button_GetCheck( GetDlgItem( hwnd, IDC_PRINTCOLOR ) ) == BST_CHECKED ? TRUE : FALSE; hr = pPersistQuery->WriteInt( c_szMsPrintersMore, c_szColor, i ); FailGracefully(hr, "Failed to write color state");
i = Button_GetCheck( GetDlgItem( hwnd, IDC_PRINTDUPLEX ) ) == BST_CHECKED ? TRUE : FALSE; hr = pPersistQuery->WriteInt( c_szMsPrintersMore, c_szDuplex, i ); FailGracefully(hr, "Failed to write duplex state");
i = Button_GetCheck( GetDlgItem( hwnd, IDC_PRINTSTAPLE ) ) == BST_CHECKED ? TRUE : FALSE; hr = pPersistQuery->WriteInt( c_szMsPrintersMore, c_szStaple, i ); FailGracefully(hr, "Failed to write staple state");
i = (INT)ComboBox_GetCurSel( GetDlgItem( hwnd, IDC_PRINTRES ) ); hr = pPersistQuery->WriteInt( c_szMsPrintersMore, c_szResolution, i ); FailGracefully(hr, "Failed to write resolution state");
i = (INT)SendMessage( GetDlgItem( hwnd, IDC_PRINTSPEED_UPDN ), UDM_GETPOS, 0, 0 ); hr = pPersistQuery->WriteInt( c_szMsPrintersMore, c_szSpeed, LOWORD(i) ); FailGracefully(hr, "Failed to write speed state");
ComboBox_GetText( GetDlgItem( hwnd, IDC_PRINTPAGESIZE ), szBuffer, ARRAYSIZE( szBuffer ) ); hr = pPersistQuery->WriteString( c_szMsPrintersMore, c_szPaperSize, szBuffer ); FailGracefully(hr, "Failed to write paper size state");
}
FailGracefully(hr, "Failed to persist page");
break; }
case CQPM_HELP: { LPHELPINFO pHelpInfo = (LPHELPINFO)lParam; WinHelp((HWND)pHelpInfo->hItemHandle, DSQUERY_HELPFILE, HELP_WM_HELP, (DWORD_PTR)aFormHelpIDs); break; }
case DSQPM_GETCLASSLIST: // the PageProc_Printers will have already handled this, no need to do it again! (daviddv, 19jun98)
break;
default: hr = E_NOTIMPL; break; }
exit_gracefully:
TraceLeaveResult(hr); }
/*-----------------------------------------------------------------------------
/ DlgProc_Printers / ---------------- / Standard dialog proc for the form, handle any special buttons and other / such nastyness we must here. / / In: / hwnd, uMsg, wParam, lParam = standard parameters / / Out: / INT_PTR /----------------------------------------------------------------------------*/ INT_PTR CALLBACK DlgProc_PrintersMore(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { INT_PTR fResult = FALSE; LPCQPAGE pQueryPage = NULL;
if ( uMsg == WM_INITDIALOG ) { pQueryPage = (LPCQPAGE)lParam;
SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR)pQueryPage);
//
// Fill in the printer forms combo-box.
//
PopulatePrintPageSize( hwnd );
//
// Fill in the print speed combo-box.
//
PopulatePrintSpeed( hwnd );
//
// Fill in the print speed combo-box.
//
PopulatePrintResolution( hwnd ); } else if ( uMsg == WM_CONTEXTMENU ) { WinHelp((HWND)wParam, DSQUERY_HELPFILE, HELP_CONTEXTMENU, (DWORD_PTR)aFormHelpIDs); fResult = TRUE; }
return fResult; }
|