/*++ Copyright (c) 1990-2003 Microsoft Corporation All Rights Reserved Module Name: cpsuisam.c Abstract: This module contrains sample prototype for the Windows 2000/Windows XP/Windows Server 2003 common Property Sheet user interface --*/ #include "precomp.h" #pragma hdrstop #define DBG_CPSUIFILENAME DbgCPSUISam #define DBG_WINMAINPROC 0x00000001 DEFINE_DBGVAR(0); #define HAS_TVTEST_PAGES 0x01 #define HAS_DOCPROP_PAGES 0x02 extern HINSTANCE hInstApp; extern TCHAR TitleName[]; extern TCHAR ClassName[]; extern TCHAR MenuName[]; extern TCHAR szWinSpool[]; extern CHAR szDocPropSheets[]; extern BOOL UpdatePermission; extern BOOL UseStdAbout; HWND hWndApp = NULL; typedef struct _CPSUISAMPLE { HANDLE hParent; HANDLE hCPSUI; HANDLE hDocProp; PFNCOMPROPSHEET pfnCPS; COMPROPSHEETUI CPSUI; DOCUMENTPROPERTYHEADER DPHdr; HGLOBAL hDevMode; HGLOBAL hDevNames; } CPSUISAMPLE, *PCPSUISAMPLE; BOOL GetDefPrinter ( PCPSUISAMPLE pCPSUISample ) { HGLOBAL h; LPTSTR pszPrinterName; DEVMODE *pDM; DEVNAMES *pDN; HANDLE hPrinter = NULL; PAGESETUPDLG PSD; BOOL Ok = FALSE; ZeroMemory(&PSD, sizeof(PSD)); PSD.lStructSize = sizeof(PSD); PSD.Flags = PSD_RETURNDEFAULT; if (PageSetupDlg(&PSD)) { if ( (h = PSD.hDevMode) && (pDM = (DEVMODE *)GlobalLock(h)) && (h = PSD.hDevNames) && (pDN = (DEVNAMES *)GlobalLock(h)) && (pszPrinterName = (LPTSTR)((LPBYTE)pDN + pDN->wDeviceOffset)) && (OpenPrinter(pszPrinterName, &hPrinter, NULL)) ) { Ok = TRUE; } if (Ok) { if (h = pCPSUISample->hDevMode) { GlobalUnlock(h); GlobalFree(h); } if (h = pCPSUISample->hDevNames) { GlobalUnlock(h); GlobalFree(h); } if (pCPSUISample->DPHdr.hPrinter) { ClosePrinter(pCPSUISample->DPHdr.hPrinter); } pCPSUISample->hDevMode = PSD.hDevMode; pCPSUISample->hDevNames = PSD.hDevNames; pCPSUISample->DPHdr.cbSize = sizeof(DOCUMENTPROPERTYHEADER); pCPSUISample->DPHdr.hPrinter = hPrinter; pCPSUISample->DPHdr.pszPrinterName = pszPrinterName; pCPSUISample->DPHdr.pdmIn = pCPSUISample->DPHdr.pdmOut = pDM; pCPSUISample->DPHdr.fMode = (DM_IN_BUFFER | DM_IN_PROMPT | DM_OUT_BUFFER); if (!UpdatePermission) { pCPSUISample->DPHdr.fMode |= DM_NOPERMISSION; } } else { if (h = PSD.hDevMode) { GlobalUnlock(h); GlobalFree(h); } if (h = PSD.hDevNames) { GlobalUnlock(h); GlobalFree(h); } if (hPrinter) { ClosePrinter(hPrinter); } } } return Ok; } LONG CALLBACK CPSUIFunc ( PPROPSHEETUI_INFO pPSUIInfo, LPARAM lParam ) { PPROPSHEETUI_INFO_HEADER pPSUIInfoHdr; PCPSUISAMPLE pCPSUISample; HANDLE h; INSERTPSUIPAGE_INFO InsPI; if (!pPSUIInfo) { return FALSE; } switch (pPSUIInfo->Reason) { case PROPSHEETUI_REASON_INIT: if (!(pCPSUISample = (PCPSUISAMPLE)LocalAlloc(LPTR, sizeof(CPSUISAMPLE)))) { return(-1); } pPSUIInfo->UserData = (ULONG_PTR)pCPSUISample; pCPSUISample->hParent = pPSUIInfo->hComPropSheet; pCPSUISample->pfnCPS = pPSUIInfo->pfnComPropSheet; // // Add Document Property Sheet for current default Printer // switch (pPSUIInfo->lParamInit) { case IDM_DOCPROP: case IDM_DOCPROP_TVTEST: if (GetDefPrinter(pCPSUISample)) { InsPI.cbSize = sizeof(INSERTPSUIPAGE_INFO); InsPI.Type = PSUIPAGEINSERT_DLL; InsPI.Mode = INSPSUIPAGE_MODE_FIRST_CHILD; InsPI.dwData1 = (ULONG_PTR)szWinSpool; InsPI.dwData2 = (ULONG_PTR)szDocPropSheets; InsPI.dwData3 = (ULONG_PTR)&(pCPSUISample->DPHdr); pCPSUISample->hDocProp = (HANDLE)pCPSUISample->pfnCPS( pCPSUISample->hParent, CPSFUNC_INSERT_PSUIPAGE, (LPARAM)0, (LPARAM)&InsPI ); } break; } // // Add TreeView Page // switch (pPSUIInfo->lParamInit) { case IDM_TVTEST: case IDM_DOCPROP_TVTEST: if (SetupComPropSheetUI(&(pCPSUISample->CPSUI))) { InsPI.cbSize = sizeof(INSERTPSUIPAGE_INFO); InsPI.Type = PSUIPAGEINSERT_PCOMPROPSHEETUI; InsPI.Mode = INSPSUIPAGE_MODE_FIRST_CHILD; InsPI.dwData1 = (ULONG_PTR)&(pCPSUISample->CPSUI); InsPI.dwData2 = InsPI.dwData3 = 0; pCPSUISample->hCPSUI = (HANDLE)pCPSUISample->pfnCPS( pCPSUISample->hParent, CPSFUNC_INSERT_PSUIPAGE, (LPARAM)0, (LPARAM)&InsPI ); } break; } if ( (pCPSUISample->hCPSUI) || (pCPSUISample->hDocProp) ) { return 1; } break; case PROPSHEETUI_REASON_GET_INFO_HEADER: if (pPSUIInfoHdr = (PPROPSHEETUI_INFO_HEADER)lParam) { pPSUIInfoHdr->pTitle = (LPTSTR)TitleName; switch (pPSUIInfo->lParamInit) { case IDM_DOCPROP: pPSUIInfoHdr->IconID = IDI_CPSUI_PRINTER2; break; case IDM_TVTEST: pPSUIInfoHdr->IconID = IDI_CPSUI_OPTION2; break; case IDM_DOCPROP_TVTEST: pPSUIInfoHdr->IconID = IDI_CPSUI_RUN_DIALOG; break; } pPSUIInfoHdr->Flags = PSUIHDRF_PROPTITLE | PSUIHDRF_NOAPPLYNOW; pPSUIInfoHdr->hWndParent = hWndApp; pPSUIInfoHdr->hInst = hInstApp; return 1; } break; case PROPSHEETUI_REASON_SET_RESULT: if ( (pCPSUISample = (PCPSUISAMPLE)pPSUIInfo->UserData) && (pCPSUISample->hCPSUI == ((PSETRESULT_INFO)lParam)->hSetResult) ) { // // Save the result and propagate to its owner // pPSUIInfo->Result = ((PSETRESULT_INFO)lParam)->Result; return 1; } break; case PROPSHEETUI_REASON_DESTROY: if (pCPSUISample = (PCPSUISAMPLE)pPSUIInfo->UserData) { if (h = pCPSUISample->hDevMode) { GlobalUnlock(h); GlobalFree(h); } if (h = pCPSUISample->hDevNames) { GlobalUnlock(h); GlobalFree(h); } if (pCPSUISample->DPHdr.hPrinter) { ClosePrinter(pCPSUISample->DPHdr.hPrinter); } LocalFree((HLOCAL)pCPSUISample); pPSUIInfo->UserData = 0; } return 1; } return -1; } LRESULT CALLBACK MainWndProc ( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam ) /*++ Routine Description: This is the main window procedure to the testing program Arguments: See SDK Return Value: See SDK --*/ { LONG Result; LONG Ret; switch (Msg) { case WM_INITMENUPOPUP: if (!HIWORD(lParam)) { CheckMenuItem( (HMENU)UIntToPtr((UINT)wParam), IDM_PERMISSION, MF_BYCOMMAND | ((UpdatePermission) ? MF_CHECKED : MF_UNCHECKED) ); CheckMenuItem( (HMENU)UIntToPtr((UINT)wParam), IDM_USESTDABOUT, MF_BYCOMMAND | ((UseStdAbout) ? MF_CHECKED : MF_UNCHECKED) ); } break; case WM_COMMAND: switch (wParam) { case IDM_USESTDABOUT: UseStdAbout = !UseStdAbout; break; case IDM_PERMISSION: UpdatePermission = !UpdatePermission; break; case IDM_DOCPROP: case IDM_TVTEST: case IDM_DOCPROP_TVTEST: Ret = CommonPropertySheetUI( hWnd, (PFNPROPSHEETUI)CPSUIFunc, (LPARAM)LOWORD(wParam), &Result ); CPSUIDBG( DBG_WINMAINPROC, ("CommonPropertySheetUI()=%ld, Result=%ld", Ret, Result) ); break; default: break; } break; case WM_DESTROY: PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, Msg, wParam, lParam)); } return 0L; } BOOL InitInstance ( HANDLE hInstance, INT nCmdShow ) /*++ Routine Description: Saves instance handle and creates main window This function is called at initialization time for every instance of this application. This function performs initialization tasks that cannot be shared by multiple instances. In this case, we save the instance handle in a static variable and create and display the main program window. Arguments: hInstance - Current instance identifier nComShow - Param for first ShowWindow() call. Return Value: TRUE/FALSE --*/ { // // Save the instance handle in static variable, which will be used in // many subsequence calls from this application to Windows. // hInstApp = hInstance; // // Create a main window for this application instance. // if (hWndApp = CreateWindow( ClassName, TitleName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL ) ) { // // Make the window visible; update its client area; // and send WM_PAINT message // ShowWindow(hWndApp, nCmdShow); UpdateWindow(hWndApp); } return ((hWndApp) ? TRUE : FALSE); } BOOL InitApplication ( HANDLE hInstance ) /*++ Routine Description: Initializes window data and registers window class This function is called at initialization time only if no other instances of the application are running. This function performs initialization tasks that can be done once for any number of running instances. In this case, we initialize a window class by filling out a data structure of type WNDCLASS and calling the Windows RegisterClass() function. Since all instances of this application use the same window class, we only need to do this when the first instance is initialized. Arguments: hInstance - current instance Return Value: BOOLEAN --*/ { WNDCLASS wc; // // Fill in window class structure with parameters that describe the // main window. // wc.style = 0L; wc.lpfnWndProc = MainWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_CPSUISAMPLE); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = GetStockObject(WHITE_BRUSH); wc.lpszMenuName = MenuName; wc.lpszClassName = ClassName; // // Register the window class and return success/failure code. // return RegisterClass(&wc); } INT APIENTRY WinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nCmdShow ) /*++ Routine Description: calls initialization function, processes message loop Windows recognizes this function by name as the initial entry point for the program. This function calls the application initialization routine, if no other instance of the program is running, and always calls the instance initialization routine. It then executes a message retrieval and dispatch loop that is the top-level control structure for the remainder of execution. The loop is terminated when a WM_QUIT message is received, at which time this function exits the application instance by returning the value passed by PostQuitMessage(). If this function must abort before entering the message loop, it returns the conventional value NULL. Arguments: Return Value: Integer --*/ { MSG Msg; UNREFERENCED_PARAMETER(lpCmdLine); // // Other instances of app running? // if (!hPrevInstance) { if (!InitApplication(hInstance)) { // // Initialize shared things, Exits if unable to initialize // return FALSE; } } // // Perform initializations that apply to a specific instance // if (!InitInstance(hInstance, nCmdShow)) { return FALSE; } // // Acquire and dispatch messages until a WM_QUIT message is received. // while (GetMessage(&Msg, NULL, 0L, 0L)) { // // Translates virtual key codes and Dispatches message to window // TranslateMessage(&Msg); DispatchMessage(&Msg); } // // Returns the value from PostQuitMessage // return((INT)Msg.wParam); }