|
|
1.1 root 1: /******************************************************************************\
2: *
3: * MODULE: TOOLBAR.C
4: *
5: * PURPOSE: Implements toobar for PRINTER sample
6: *
7: * FUNTIONS: ToolbarProc() - toolbar dlg proc
8: * UpdateToolbarCombobox() - inserts printers in toolbar combobox
9: * vDrawBitmap() - draws toolbar buttons
10: * iGetBtn() - retrieves button index
11: * vDoBtnCmd() - implements button-specific code
12: * PrintThread() - printing thread
13: *
14: \******************************************************************************/
15:
16: #include <windows.h>
17: #include <commdlg.h>
18: #include <cderr.h>
19: #include <winspool.h>
20: #include <string.h>
21: #include "lookup.h"
22: #include "printer.h"
23: #include "paint.h"
24: #include "toolbar.h"
25: #include "vars.h"
26:
27:
28:
29: /************************************************************************\
30: *
31: * FUNCTION: ToolbarProc (standard dialog procedure INPUTS/RETURNS)
32: *
33: * GLOBAL VARS: hWndToolbar - toolbar window handle
34: * DriverName - of current printer
35: * DeviceName - of current printer
36: * Port - of current printer
37: *
38: \************************************************************************/
39:
40: BOOL APIENTRY ToolbarProc (HWND hDlg,UINT message,UINT wParam,LONG lParam)
41: {
42: static HBITMAP ahbmUpBtn[MAXBUTTONS], ahbmDnBtn[MAXBUTTONS];
43:
44: static int iCurrBtn, iLastBtn;
45:
46: int i;
47:
48: switch (message)
49: {
50: case WM_INITDIALOG:
51:
52: hWndToolbar = hDlg;
53:
54: ahbmUpBtn[DID_PRTDLG] = LoadBitmap (hInst, "prtdlgup");
55: ahbmUpBtn[DID_PRINT] = LoadBitmap (hInst, "printup");
56: ahbmUpBtn[DID_ENUM] = LoadBitmap (hInst, "enumup");
57: ahbmUpBtn[DID_DEVCAP] = LoadBitmap (hInst, "devcapup");
58: ahbmUpBtn[DID_DELTA] = LoadBitmap (hInst, "deltaup");
59:
60: ahbmDnBtn[DID_PRTDLG] = LoadBitmap (hInst, "prtdlgdn");
61: ahbmDnBtn[DID_PRINT] = LoadBitmap (hInst, "printdn");
62: ahbmDnBtn[DID_ENUM] = LoadBitmap (hInst, "enumdn");
63: ahbmDnBtn[DID_DEVCAP] = LoadBitmap (hInst, "devcapdn");
64: ahbmDnBtn[DID_DELTA] = LoadBitmap (hInst, "deltadn");
65:
66: SetWindowPos (hDlg, HWND_TOP, -1, 0,
67: GetSystemMetrics (SM_CXFULLSCREEN) + 2,
68: TOOLBARHEIGHT, SWP_SHOWWINDOW);
69: SetWindowPos (GetDlgItem (hDlg, DID_TOOLBARCOMBO),
70: HWND_TOP, 11*BUTTONWIDTH/2, 6, BUTTONWIDTH*8,
71: BUTTONWIDTH*4, SWP_SHOWWINDOW);
72:
73: UpdateToolbarCombobox (hDlg);
74:
75: break;
76:
77: case WM_PAINT:
78: {
79: PAINTSTRUCT ps;
80:
81: BeginPaint (hDlg, &ps);
82: FillRect (ps.hdc, &ps.rcPaint, GetStockObject (GRAY_BRUSH));
83:
84: for (i = 0; i < MAXBUTTONS; i++)
85: vDrawBitmap (ps.hdc, ahbmUpBtn[i], i*BUTTONWIDTH, 0);
86:
87: MoveToEx (ps.hdc, BUTTONWIDTH*5, 0, NULL);
88: LineTo (ps.hdc, BUTTONWIDTH*5, TOOLBARHEIGHT);
89: EndPaint (hDlg, &ps);
90: break;
91: }
92:
93: case WM_LBUTTONDOWN:
94:
95: if ((iCurrBtn = iGetBtn (lParam)) >= 0)
96: {
97: HDC hdc = GetDC (hDlg);
98: iLastBtn = iCurrBtn;
99: vDrawBitmap (hdc, ahbmDnBtn[iCurrBtn], iCurrBtn*BUTTONWIDTH, 0);
100: ReleaseDC (hDlg, hdc);
101: SetCapture (hDlg);
102: }
103: break;
104:
105: case WM_MOUSEMOVE:
106:
107: if (GetCapture() == hDlg)
108: {
109: HDC hdc = GetDC (hDlg);
110:
111: if ((iCurrBtn = iGetBtn (lParam)) >= 0 && iCurrBtn != iLastBtn)
112:
113: vDrawBitmap (hdc, ahbmDnBtn[iCurrBtn], iCurrBtn*BUTTONWIDTH, 0);
114:
115: if ((iCurrBtn != iLastBtn) && (iLastBtn >= 0))
116:
117: vDrawBitmap (hdc, ahbmUpBtn[iLastBtn], iLastBtn*BUTTONWIDTH, 0);
118:
119: ReleaseDC (hDlg, hdc);
120: iLastBtn = iCurrBtn;
121: }
122: break;
123:
124: case WM_LBUTTONUP:
125:
126: if (GetCapture() == hDlg)
127: {
128: if ((iCurrBtn = iGetBtn (lParam)) >= 0)
129: {
130: HDC hdc = GetDC (hDlg);
131:
132: vDrawBitmap (hdc, ahbmUpBtn[iCurrBtn], iCurrBtn*BUTTONWIDTH, 0);
133:
134: ReleaseDC (hDlg, hdc);
135:
136: vDoBtnCmd (iCurrBtn);
137: }
138: ReleaseCapture ();
139: }
140: break;
141:
142: case WM_COMMAND:
143:
144: switch (LOWORD(wParam))
145: {
146: case DID_TOOLBARCOMBO:
147:
148: switch (HIWORD(wParam))
149: {
150: case CBN_SELCHANGE:
151: {
152: DWORD dwIndex;
153: char buf[256];
154:
155: /****************************************************************\
156: * User clicked on one of the items in the toolbar combobox;
157: * figure out which item, then parse the text apart and
158: * copy it to the DriverName, DeviceName, and Port
159: * variables.
160: \****************************************************************/
161:
162: dwIndex = (DWORD) SendMessage ((HWND) lParam,
163: CB_GETCURSEL, 0, 0);
164: SendMessage ((HWND) lParam, CB_GETLBTEXT, dwIndex,
165: (LONG) buf);
166:
167: if (!strcmp (buf, "Display"))
168: {
169: strcpy (DeviceName, "Display");
170: EnableWindow (GetDlgItem (hDlg, DID_PRINT), FALSE);
171: }
172: else
173: { int i = -1, j = 0;
174:
175: while (buf[++i] != ';') DeviceName[i] = buf[i];
176: DeviceName[i] = '\0';
177: while (buf[++i] != ';') Port[j++] = buf[i];
178: Port[j] = '\0';
179: j = 0;
180: while (buf[++i] != '\0') DriverName[j++] = buf[i];
181: DriverName[j] = '\0';
182: EnableWindow (GetDlgItem (hDlg, DID_PRINT), TRUE);
183: }
184: break;
185: }
186: }
187: break;
188: }
189: break;
190:
191: default:
192:
193: return FALSE;
194: }
195: return (TRUE);
196: }
197:
198:
199:
200: /******************************************************************************\
201: *
202: * FUNCTION: UpdateToolbarCombobox
203: *
204: * GLOBAL VARS: hWndToolbar - toolbar window handle
205: *
206: * LOCAL VARS: dwEnumFlags - which printers to enumerate
207: * dwBytesNeeded - # of bytes required to contain
208: * PRINTER_INFO_2 info for all printers
209: * pwPrtRet - number of printers (info) returned
210: * pPrtInfo2 - pointer to PRINTER_INFO_2 structs
211: * i - loop variable
212: *
213: * COMMENTS: The idea here is to enumerate all printers & list them in
214: * then combobox in the form: "DEVICE_NAME;PORT;DRIVER_NAME".
215: * Then later, when a user selects one of these, we just
216: * query out the string & parse it apart, sticking the
217: * appropriate parts into the DriverName, DeviceName, and
218: * Port variables.
219: *
220: * Also, the "Display" option is added to the combobox so
221: * that user can get DevCaps info about it.
222: *
223: \******************************************************************************/
224:
225: void UpdateToolbarCombobox (HWND hDlg)
226: {
227: DWORD dwFlags = PRINTER_ENUM_FAVORITE | PRINTER_ENUM_LOCAL;
228: LPPRINTER_INFO_2 pPrinters;
229: DWORD cbPrinters;
230: DWORD cReturned, i;
231: char buf[256];
232:
233: EnumPrinters (dwFlags, NULL, 2, NULL, 0, &cbPrinters,
234: &cReturned);
235:
236: pPrinters = (LPPRINTER_INFO_2) LocalAlloc (LPTR, cbPrinters + 4);
237:
238: EnumPrinters (dwFlags, NULL, 2, (LPBYTE) pPrinters,
239: cbPrinters, &cbPrinters, &cReturned);
240:
241: SendDlgItemMessage (hDlg, DID_TOOLBARCOMBO, CB_RESETCONTENT, 0, 0);
242:
243: for (i = 0; i < cReturned; i++)
244: {
245: /**************************************************************************\
246: * for each printer in the PRINTER_INFO_2 array: build a string that
247: * looks like "DEVICE_NAME;PORT;DRIVER_NAME"
248: \**************************************************************************/
249:
250: strcpy (buf, (pPrinters + i)->pPrinterName);
251: strcat (buf, ";");
252: strcat (buf, (pPrinters + i)->pPortName);
253: strcat (buf, ";");
254: strcat (buf, (pPrinters + i)->pDriverName);
255:
256: SendDlgItemMessage (hDlg, DID_TOOLBARCOMBO, CB_INSERTSTRING, (UINT)-1,
257: (LONG) buf);
258: }
259:
260: SendDlgItemMessage (hDlg, DID_TOOLBARCOMBO, CB_INSERTSTRING, (UINT)-1,
261: (LONG) "Display");
262:
263: SendDlgItemMessage (hDlg, DID_TOOLBARCOMBO, CB_SELECTSTRING, (UINT)-1,
264: (LONG) buf);
265:
266: SendMessage (hDlg, WM_COMMAND,
267: (UINT) MAKELONG (DID_TOOLBARCOMBO, CBN_SELCHANGE),
268: (LONG) GetDlgItem (hDlg, DID_TOOLBARCOMBO));
269: }
270:
271:
272:
273: /******************************************************************************\
274: *
275: * FUNCTION: vDrawBitmap
276: *
277: * INPUTS: hdc - device context in which to draw bitmap
278: * hbm - handle of bitmap to draw
279: * xStart - x-coordinate of upper-left corner of destination
280: * rectangle
281: * yStart - y-coordinate of upper-left corner of destination
282: * rectangle
283: *
284: * LOCAL VARS: bm - BITMAP info of "hbm"
285: * hdcMem - a memory DC used for blt-ing
286: *
287: * COMMENTS: Draws a bitmap "hbm" in a DC "hdc" given the upper-left
288: * corner "xStart,yStart" of a destination rectangle.
289: *
290: \******************************************************************************/
291:
292: void vDrawBitmap (HDC hdc, HBITMAP hbm, int xStart, int yStart)
293: {
294: BITMAP bm;
295: HDC hdcMem;
296:
297: hdcMem = CreateCompatibleDC (hdc);
298: SelectObject (hdcMem, hbm);
299: SetMapMode (hdcMem, GetMapMode(hdc));
300:
301: GetObject (hbm, sizeof(BITMAP), (LPSTR)&bm);
302: BitBlt (hdc, xStart, yStart, bm.bmWidth, bm.bmHeight,
303: hdcMem, 0, 0, SRCCOPY);
304:
305: DeleteDC(hdcMem);
306: }
307:
308:
309:
310: /******************************************************************************\
311: *
312: * FUNCTION: iGetBtn
313: *
314: * INPUTS: lParam - lParam of a WM_MOUSEMOVE/WM_LBUTTON* msg
315: *
316: * RETURNS: Index of button, or
317: * -1 if no button in specified position
318: *
319: * LOCAL VARS: xPos - x position of mouse
320: *
321: * COMMENTS: Given an x,y position (in an lParam) finds the corresponding
322: * toolbar button
323: *
324: \******************************************************************************/
325:
326: int iGetBtn (LONG lParam)
327: {
328: int xPos = (int) LOWORD (lParam), i;
329:
330: for (i = 1; i <= MAXBUTTONS; i++)
331:
332: if (xPos <= i*BUTTONWIDTH)
333:
334: return i-1;
335:
336: return -1;
337: }
338:
339:
340:
341: /******************************************************************************\
342: *
343: * FUNCTION: vDoBtnCmd
344: *
345: * INPUTS: cmd - index of which button pressed
346: *
347: * GLOBAL VARS: hWndMain - main app window handle
348: * hInst - app instance
349: *
350: * COMMENTS: Implements button-specific code
351: *
352: \******************************************************************************/
353:
354: void vDoBtnCmd (int cmd)
355: {
356: switch (cmd)
357: {
358: case DID_PRTDLG:
359: case DID_PRINT:
360: {
361: LPVOID lpArg;
362: DWORD threadId;
363:
364: /************************************************************************\
365: * Start a print thread, passing it either NULL or 0xffffffff
366: * if we want to call PrintDlg or do a CreateDC, respectively.
367: \************************************************************************/
368:
369: if (cmd == DID_PRINT)
370: lpArg = (LPVOID) 0xffffffff;
371: else
372: lpArg = NULL;
373:
374: if (!CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) PrintThread,
375: lpArg, NULL, &threadId))
376: MessageBox (hWndMain,
377: "MainWndProc(): Error creating print thread",
378: "Err! - PRINTX", MB_OK | MB_ICONHAND);
379: break;
380: }
381: case DID_ENUM:
382:
383: DialogBox (hInst, "AboutBox", hWndMain, (DLGPROC)EnumDlgProc);
384: break;
385:
386: case DID_DEVCAP:
387:
388: DialogBox (hInst, "AboutBox", hWndMain, (DLGPROC)DevCapDlgProc);
389: break;
390:
391: case DID_DELTA:
392:
393: UpdateToolbarCombobox (hWndToolbar);
394: break;
395: }
396: }
397:
398:
399:
400: /******************************************************************************\
401: *
402: * FUNCTION: PrintThread
403: *
404: * INPUTS: arg - if nonzero then open a printer DC using CreateDC,
405: * else call PRintDlg() to get a printer DC.
406: *
407: * GLOBAL VARS: DriverName - of current printer
408: * DeviceName - of current printer
409: * Port - of current printer
410: * hwndMain - main app window handle
411: * iMapMode - current map mode
412: *
413: * LOCAL VARS: hdc - printer DC
414: * di - required struct for calling PrintDlg()
415: * rect - scratch rectangle
416: *
417: \******************************************************************************/
418:
419: void PrintThread (LPVOID arg)
420: {
421: HDC hdc;
422: DOCINFO di;
423: RECT rect;
424:
425: if (arg)
426: {
427: if (!strcmp (DeviceName, "Display"))
428: {
429: MessageBox (hWndMain, "You must select a printer",
430: "PRINTER.EXE: Error creating DC", MB_OK);
431: return;
432: }
433: else if (!(hdc = CreateDC (DriverName, DeviceName, Port, NULL)))
434: {
435: MessageBox (hWndMain, "PrintThread(): CreateDC() failed",
436: "Err! - PRINTX", MB_OK);
437: return;
438: }
439: }
440: else
441: {
442: PRINTDLG pd;
443:
444: /**************************************************************************\
445: * Initialize a PRINTDLG struct and call PrintDlg to allow user to
446: * specify various printing options...
447: \**************************************************************************/
448:
449: memset (&pd, 0, sizeof(PRINTDLG));
450:
451: pd.lStructSize = sizeof(PRINTDLG);
452: pd.hwndOwner = hWndMain;
453: pd.Flags = PD_RETURNDC | PD_PRINTSETUP;
454: pd.hInstance = NULL;
455:
456: PrintDlg(&pd);
457: hdc = pd.hDC;
458: if (pd.hDevMode)
459: GlobalFree (pd.hDevMode);
460: if (pd.hDevNames)
461: GlobalFree (pd.hDevNames);
462: if (!hdc)
463: return;
464: }
465:
466: SetMapMode (hdc, iMapMode);
467: rect.right = GetDeviceCaps (hdc, HORZRES);
468: rect.bottom = GetDeviceCaps (hdc, VERTRES);
469: di.cbSize = sizeof(DOCINFO);
470: di.lpszDocName = "print test";
471: di.lpszOutput = NULL;
472:
473: StartDoc (hdc, &di);
474: StartPage (hdc);
475: Paint (hdc, &rect);
476: EndPage (hdc);
477: EndDoc (hdc);
478: DeleteDC (hdc);
479: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.