|
|
1.1 root 1: /****************************************************************************/
2: /* */
3: /* Microsoft Confidential */
4: /* */
5: /* Copyright (c) Microsoft Corp. 1987, 1990 */
6: /* All Rights Reserved */
7: /* */
8: /****************************************************************************/
9: /****************************** Module Header *******************************
10: * Module Name: toolbox.c
11: *
12: * Contains routines that handle the toolbox.
13: *
14: * History:
15: *
16: * 04/30/91 - Copied from DlgEdit.
17: *
18: ****************************************************************************/
19:
20: #include "imagedit.h"
21: #include "dialogs.h"
22:
23:
24: #define TOOLBOXCOLUMNS 2 // Columns in the Toolbox.
25:
26: /*
27: * Style of the toolbox window.
28: */
29: #define TOOLBOXSTYLE (WS_POPUP | WS_CLIPSIBLINGS | WS_CAPTION | WS_SYSMENU)
30:
31:
32: STATICFN VOID NEAR ToolboxDrawBitmap(HDC hDC, INT tool);
33:
34:
35: /*
36: * Dimensions of a tool button bitmap.
37: */
38: static INT cxToolBtn;
39: static INT cyToolBtn;
40:
41: /*
42: * Index to the last available tool. If tools at the end of the
43: * toolbox are disabled, this number gets lowered.
44: */
45: static INT iToolLast = CTOOLS - 1;
46:
47:
48:
49: /****************************************************************************
50: * ToolboxCreate
51: *
52: * This function creates the toolbox window.
53: *
54: * History:
55: *
56: ****************************************************************************/
57:
58: VOID ToolboxCreate(VOID)
59: {
60: BITMAP bmp;
61: INT i;
62: INT x;
63: INT y;
64: INT cx;
65: INT cy;
66: INT cxDummy;
67: INT cyDummy;
68: RECT rc;
69: RECT rcClient;
70: POINT pt;
71: BOOL fMaximized;
72:
73: /*
74: * Load the bitmaps.
75: */
76: for (i = 0; i < CTOOLS; i++) {
77: if (!(gaTools[i].hbmToolBtnUp = LoadBitmap(ghInst,
78: MAKEINTRESOURCE(gaTools[i].idbmToolBtnUp))))
79: return;
80:
81: if (!(gaTools[i].hbmToolBtnDown = LoadBitmap(ghInst,
82: MAKEINTRESOURCE(gaTools[i].idbmToolBtnDown))))
83: return;
84: }
85:
86: /*
87: * Get the dimensions of the tool button bitmaps.
88: */
89: GetObject(gaTools[0].hbmToolBtnUp, sizeof(BITMAP), (PSTR)&bmp);
90: cxToolBtn = bmp.bmWidth;
91: cyToolBtn = bmp.bmHeight;
92:
93: /*
94: * Calculate the required window size for the client area
95: * size we want. The size leaves room for a margin, and
96: * assumes that adjacent buttons overlap their borders by
97: * one pixel.
98: */
99: rc.left = 0;
100: rc.top = 0;
101: rc.right = PALETTEMARGIN + ((cxToolBtn - 1) * 2) + 1 + PALETTEMARGIN;
102: rc.bottom = PALETTEMARGIN + ((cyToolBtn - 1) *
103: (CTOOLS / 2)) + 1 + PALETTEMARGIN;
104: AdjustWindowRect(&rc, TOOLBOXSTYLE, FALSE);
105: cx = rc.right - rc.left;
106: cy = rc.bottom - rc.top;
107:
108: /*
109: * Get the saved position of the Toolbox. Note that we throw away
110: * the size fields, because we just calculated the required size.
111: */
112: if (!ReadWindowPos(szTBPos, &x, &y, &cxDummy, &cyDummy, &fMaximized)) {
113: /*
114: * The previous position of the Toolbox couldn't be found.
115: * Position the toolbox to the upper right corner of the
116: * client area of the editor, but make sure it is completely
117: * visible.
118: */
119: GetClientRect(ghwndMain, &rcClient);
120: pt.x = rcClient.right - cx - (2 * PALETTEMARGIN);
121: pt.y = rcClient.top + gcyPropBar + (2 * PALETTEMARGIN);
122: ClientToScreen(ghwndMain, &pt);
123: SetRect(&rc, pt.x, pt.y, pt.x + cx, pt.y + cy);
124: FitRectToScreen(&rc);
125: x = rc.left;
126: y = rc.top;
127: }
128:
129: if (!(ghwndToolbox = CreateWindow(szToolboxClass, NULL, TOOLBOXSTYLE,
130: x, y, cx, cy, ghwndMain, NULL, ghInst, NULL)))
131: return;
132:
133: /*
134: * Create the buttons.
135: */
136: x = PALETTEMARGIN;
137: y = PALETTEMARGIN;
138: for (i = 0; i < CTOOLS; i++) {
139: CreateWindow(szToolBtnClass, NULL,
140: WS_CHILD | WS_VISIBLE,
141: x, y, cxToolBtn, cyToolBtn,
142: ghwndToolbox, (HMENU)i, ghInst, NULL);
143:
144: if (x == PALETTEMARGIN) {
145: x += cxToolBtn - 1;
146: }
147: else {
148: x = PALETTEMARGIN;
149: y += cyToolBtn - 1;
150: }
151: }
152:
153: ToolboxUpdate();
154: }
155:
156:
157:
158: /****************************************************************************
159: * ToolboxShow
160: *
161: * This function shows or hides the toolbox window.
162: *
163: * History:
164: *
165: ****************************************************************************/
166:
167: VOID ToolboxShow(
168: BOOL fShow)
169: {
170: if (fShow)
171: ShowWindow(ghwndToolbox, SW_SHOWNA);
172: else
173: ShowWindow(ghwndToolbox, SW_HIDE);
174: }
175:
176:
177:
178: /****************************************************************************
179: * ToolboxUpdate
180: *
181: * This function updates the toolbox. It should be called any time that
182: * a new file is opened/created for editing.
183: *
184: * History:
185: *
186: ****************************************************************************/
187:
188: VOID ToolboxUpdate(VOID)
189: {
190: if (!ghwndToolbox)
191: return;
192:
193: if (giType == FT_CURSOR) {
194: ShowWindow(GetDlgItem(ghwndToolbox, TOOL_HOTSPOT), SW_SHOWNA);
195: iToolLast = CTOOLS - 1;
196: }
197: else {
198: ShowWindow(GetDlgItem(ghwndToolbox, TOOL_HOTSPOT), SW_HIDE);
199: iToolLast = TOOL_HOTSPOT - 1;
200: if (gCurTool == TOOL_HOTSPOT)
201: ToolboxSelectTool(TOOL_FIRST);
202: }
203: }
204:
205:
206:
207: /****************************************************************************
208: * ToolboxWndProc
209: *
210: * This is the window procedure for the toolbox window.
211: *
212: * History:
213: *
214: ****************************************************************************/
215:
216: WINDOWPROC ToolboxWndProc(
217: HWND hwnd,
218: UINT msg,
219: WPARAM wParam,
220: LPARAM lParam)
221: {
222: switch (msg) {
223: case WM_CREATE:
224: {
225: HMENU hmenu = GetSystemMenu(hwnd, FALSE);
226:
227: RemoveMenu(hmenu, 7, MF_BYPOSITION); // Second separator.
228: RemoveMenu(hmenu, 5, MF_BYPOSITION); // First separator.
229:
230: RemoveMenu(hmenu, SC_RESTORE, MF_BYCOMMAND);
231: RemoveMenu(hmenu, SC_SIZE, MF_BYCOMMAND);
232: RemoveMenu(hmenu, SC_MINIMIZE, MF_BYCOMMAND);
233: RemoveMenu(hmenu, SC_MAXIMIZE, MF_BYCOMMAND);
234: RemoveMenu(hmenu, SC_TASKLIST, MF_BYCOMMAND);
235: }
236:
237: return 0;
238:
239: case WM_KEYDOWN:
240: {
241: INT iToolNext;
242:
243: switch (wParam) {
244: case VK_UP:
245: if ((GetKeyState(VK_SHIFT) & 0x8000) ||
246: (GetKeyState(VK_CONTROL) & 0x8000))
247: break;
248:
249: /*
250: * Go up a row, but don't go beyond the top.
251: */
252: iToolNext = gCurTool - TOOLBOXCOLUMNS;
253: if (iToolNext < 0)
254: break;
255:
256: ToolboxSelectTool(iToolNext);
257:
258: break;
259:
260: case VK_DOWN:
261: if ((GetKeyState(VK_SHIFT) & 0x8000) ||
262: (GetKeyState(VK_CONTROL) & 0x8000))
263: break;
264:
265: /*
266: * Go down a row, but don't go beyond the bottom.
267: */
268: iToolNext = gCurTool + TOOLBOXCOLUMNS;
269: if (iToolNext > iToolLast)
270: break;
271:
272: ToolboxSelectTool(iToolNext);
273:
274: break;
275:
276: case VK_LEFT:
277: if ((GetKeyState(VK_SHIFT) & 0x8000) ||
278: (GetKeyState(VK_CONTROL) & 0x8000))
279: break;
280:
281: /*
282: * Already at left edge.
283: */
284: if (!(gCurTool % TOOLBOXCOLUMNS))
285: break;
286:
287: /*
288: * Go left a column.
289: */
290: ToolboxSelectTool(gCurTool - 1);
291:
292: break;
293:
294: case VK_RIGHT:
295: if ((GetKeyState(VK_SHIFT) & 0x8000) ||
296: (GetKeyState(VK_CONTROL) & 0x8000))
297: break;
298:
299: /*
300: * Already at right edge.
301: */
302: if ((gCurTool % TOOLBOXCOLUMNS) == TOOLBOXCOLUMNS - 1)
303: break;
304:
305: /*
306: * Don't go off the end of the available tools.
307: */
308: if (gCurTool + 1 > iToolLast)
309: break;
310:
311: /*
312: * Go right a column.
313: */
314: ToolboxSelectTool(gCurTool + 1);
315:
316: break;
317:
318: case VK_TAB:
319: if (GetKeyState(VK_CONTROL) & 0x8000)
320: break;
321:
322: /*
323: * Is the shift key pressed also?
324: */
325: if (GetKeyState(VK_SHIFT) & 0x8000) {
326: if (gCurTool == TOOL_FIRST)
327: iToolNext = iToolLast;
328: else
329: iToolNext = gCurTool - 1;
330: }
331: else {
332: if (gCurTool == iToolLast)
333: iToolNext = TOOL_FIRST;
334: else
335: iToolNext = gCurTool + 1;
336: }
337:
338: ToolboxSelectTool(iToolNext);
339:
340: break;
341:
342: case VK_END:
343: if ((GetKeyState(VK_SHIFT) & 0x8000) ||
344: (GetKeyState(VK_CONTROL) & 0x8000))
345: break;
346:
347: ToolboxSelectTool(iToolLast);
348:
349: break;
350:
351: case VK_HOME:
352: case VK_ESCAPE:
353: if ((GetKeyState(VK_SHIFT) & 0x8000) ||
354: (GetKeyState(VK_CONTROL) & 0x8000))
355: break;
356:
357: ToolboxSelectTool(TOOL_FIRST);
358:
359: break;
360: }
361: }
362:
363: break;
364:
365: case WM_ACTIVATE:
366: if (LOWORD(wParam))
367: gidCurrentDlg = DID_TOOLBOX;
368:
369: break;
370:
371: case WM_PAINT:
372: {
373: HDC hdc;
374: PAINTSTRUCT ps;
375:
376: hdc = BeginPaint(hwnd, &ps);
377: DrawMarginBorder(hwnd, hdc);
378: EndPaint(hwnd, &ps);
379: }
380:
381: break;
382:
383: case WM_CLOSE:
384: /*
385: * The user closed the toolbox from the system menu.
386: * Hide the toolbox (we don't actually destroy it so
387: * that it will appear in the same spot when they show
388: * it again).
389: */
390: ToolboxShow(FALSE);
391: gfShowToolbox = FALSE;
392: break;
393:
394: case WM_DESTROY:
395: {
396: INT i;
397: RECT rc;
398:
399: for (i = 0; i < CTOOLS; i++) {
400: DeleteObject(gaTools[i].hbmToolBtnUp);
401: gaTools[i].hbmToolBtnUp = NULL;
402: DeleteObject(gaTools[i].hbmToolBtnDown);
403: gaTools[i].hbmToolBtnDown = NULL;
404: }
405:
406: /*
407: * Save the position of the toolbox.
408: */
409: GetWindowRect(hwnd, &rc);
410: WriteWindowPos(&rc, FALSE, szTBPos);
411:
412: /*
413: * Null out the global window handle for the toolbox
414: * for safety's sake.
415: */
416: ghwndToolbox = NULL;
417: }
418:
419: break;
420:
421: default:
422: return DefWindowProc(hwnd, msg, wParam, lParam);
423: }
424:
425: return 0;
426: }
427:
428:
429:
430: /****************************************************************************
431: * ToolBtnWndProc
432: *
433: * This is the window procedure for the buttons in the toolbox window.
434: *
435: * History:
436: *
437: ****************************************************************************/
438:
439: WINDOWPROC ToolBtnWndProc(
440: HWND hwnd,
441: UINT msg,
442: WPARAM wParam,
443: LPARAM lParam)
444: {
445: switch (msg) {
446: case WM_LBUTTONDOWN:
447: /*
448: * Select the tool that was clicked on.
449: */
450: ToolboxSelectTool((UINT)GetWindowLong((hwnd), GWL_ID));
451:
452: break;
453:
454: case WM_PAINT:
455: {
456: HDC hDC;
457: PAINTSTRUCT ps;
458:
459: hDC = BeginPaint(hwnd, &ps);
460: ToolboxDrawBitmap(hDC, (UINT)GetWindowLong((hwnd), GWL_ID));
461: EndPaint(hwnd, &ps);
462: }
463:
464: break;
465:
466: default:
467: return DefWindowProc(hwnd, msg, wParam, lParam);
468: }
469:
470: return 0;
471: }
472:
473:
474:
475: /****************************************************************************
476: * ToolboxDrawBitmap
477: *
478: *
479: * History:
480: *
481: ****************************************************************************/
482:
483: STATICFN VOID NEAR ToolboxDrawBitmap(
484: HDC hDC,
485: INT tool)
486: {
487: HDC hMemDC;
488: HBITMAP hbmOld;
489:
490: /*
491: * Draw the image.
492: */
493: hMemDC = CreateCompatibleDC(hDC);
494: hbmOld = SelectObject(hMemDC, (tool == gCurTool) ?
495: gaTools[tool].hbmToolBtnDown : gaTools[tool].hbmToolBtnUp);
496: BitBlt(hDC, 0, 0, cxToolBtn, cyToolBtn, hMemDC, 0, 0, SRCCOPY);
497: SelectObject(hMemDC, hbmOld);
498: DeleteDC(hMemDC);
499: }
500:
501:
502:
503: /****************************************************************************
504: * ToolboxSelectTool
505: *
506: *
507: * History:
508: *
509: ****************************************************************************/
510:
511: VOID ToolboxSelectTool(
512: INT tool)
513: {
514: if (gCurTool != tool) {
515: if (ghwndToolbox) {
516: InvalidateRect(GetDlgItem(ghwndToolbox, gCurTool), NULL, FALSE); InvalidateRect(GetDlgItem(ghwndToolbox, tool), NULL, FALSE);
517: }
518:
519: gCurTool = tool;
520: gpfnDrawProc = gaTools[gCurTool].pfnDrawProc;
521: }
522: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.