source: branches/v2.9/classes/mm-progs/_pmtst/cell.c

Last change on this file was 2, checked in by stevenhl, 8 years ago

Import sources from cwmm-full.zip dated 2005-03-21

File size: 70.7 KB
Line 
1/*
2** Module :CELL.CPP
3** Abstract :Cell Toolkit
4**
5** Copyright (C) Sergey I. Yevtushenko
6** Log: Sun 08/02/98 Created.
7** Wed 25/10/2000 Updated to version 0.7b
8*/
9
10#define INCL_WIN
11#define INCL_NLS
12#define INCL_DOS
13#define INCL_GPI
14
15#include <os2.h>
16#include <string.h>
17#include <stdlib.h>
18#include <cell.h>
19
20#define TKM_SEARCH_ID WM_USER+0x1000
21#define TKM_QUERY_FLAGS WM_USER+0x1001
22#define TKM_SEARCH_PARENT WM_USER+0x1002
23
24#define TB_ATTACHED 0x00F8
25
26/*****************************************************************************
27** Static data
28*/
29
30static CHAR CELL_CLIENT[] = "Uni.Cell.Client";
31static CHAR TB_CLIENT[] = "Uni.Tb.Client";
32static CHAR TB_SEPCLASS[] = "Uni.Tb.Separator";
33static CHAR ppFont[] = "9.WarpSans";
34
35/* Color tables */
36
37static LONG lColor[SPLITBAR_WIDTH] =
38{
39 CLR_BLACK,
40#if (SPLITBAR_WIDTH>2)
41 CLR_PALEGRAY,
42#endif
43 CLR_WHITE
44};
45
46static LONG lColor2[SPLITBAR_WIDTH] =
47{
48 CLR_WHITE,
49#if (SPLITBAR_WIDTH>2)
50 CLR_PALEGRAY,
51#endif
52 CLR_BLACK
53};
54
55
56/*****************************************************************************
57** Internal prototypes
58*/
59
60MRESULT EXPENTRY CellProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
61MRESULT EXPENTRY CellClientProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
62MRESULT EXPENTRY TbProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
63MRESULT EXPENTRY TbClientProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
64MRESULT EXPENTRY TbSeparatorProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
65MRESULT EXPENTRY BtProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
66HWND CreateTb(TbDef* pTb, HWND hWndParent, HWND hWndOwner);
67void RecalcTbDimensions(HWND hwnd, POINTL *pSize);
68BOOL TrackRectangle(HWND hwndBase, RECTL* rclTrack, RECTL* rclBounds);
69
70/*****************************************************************************
71** Internal data types
72*/
73
74 /* Cell data, used by subclass proc of splitted window. */
75
76typedef struct stCellTb
77{
78 HWND hWnd;
79 struct stCellTb* pNext;
80} CellTb;
81
82typedef struct
83{
84 PFNWP pOldProc;
85 RECTL rclBnd;
86 LONG lType;
87 LONG lSplit;
88 LONG lSize;
89 HWND hwndSplitbar;
90 HWND hwndPanel1;
91 HWND hwndPanel2;
92 CellTb *pCellTb;
93} CellCtlData;
94
95 /* Toolbar data */
96
97typedef struct stTbItemData
98{
99 PFNWP pOldProc;
100 CHAR cText[TB_BUBBLE_SIZE];
101} TbItemData;
102
103typedef struct stToolbarCtlData
104{
105 PFNWP pOldProc;
106 HWND hwndParent;
107 LONG lState;
108 LONG lCount;
109
110 BOOL bBubble;
111 HWND hwndBubble;
112 HWND hwndLast;
113
114 HWND hItems[1];
115} TbCtlData;
116
117static HAB hab;
118
119/*
120******************************************************************************
121** Cell (Splitted view) implementation
122******************************************************************************
123*/
124
125void ShowCell(HWND hwnd, LONG lID, BOOL bAction)
126{
127 HWND hwndMain = hwnd;
128 CellCtlData* pCtlData = 0;
129 LONG lCell = 0;
130
131 hwnd = CellParentWindowFromID(hwnd, lID);
132
133 if(!hwnd)
134 return;
135
136 pCtlData = (CellCtlData *)WinQueryWindowULong(hwnd, QWL_USER);
137
138 if(!pCtlData)
139 return;
140
141 if(WinQueryWindowUShort(pCtlData->hwndPanel1, QWS_ID) == lID)
142 lCell = CELL_HIDE_1;
143
144 if(WinQueryWindowUShort(pCtlData->hwndPanel2, QWS_ID) == lID)
145 lCell = CELL_HIDE_2;
146
147 switch(lCell)
148 {
149 case CELL_HIDE_1:
150 if(bAction == FALSE)
151 pCtlData->lType |= CELL_HIDE_1;
152 else
153 pCtlData->lType &= ~CELL_HIDE_1;
154 break;
155
156 case CELL_HIDE_2:
157 if(bAction == FALSE)
158 pCtlData->lType |= CELL_HIDE_2;
159 else
160 pCtlData->lType &= ~CELL_HIDE_2;
161 break;
162 }
163
164 if(lCell)
165 WinSendMsg(hwnd, WM_UPDATEFRAME, 0, 0);
166}
167
168LONG GetSplit(HWND hwnd, LONG lID)
169{
170 CellCtlData* pCtlData = 0;
171
172 hwnd = CellWindowFromID(hwnd, lID);
173
174 if(!hwnd)
175 return 0;
176
177 pCtlData = (CellCtlData *)WinQueryWindowULong(hwnd, QWL_USER);
178
179 if(!pCtlData)
180 return 0;
181
182 return pCtlData->lSplit;
183}
184
185LONG SetSplit(HWND hwnd, LONG lID, LONG lNewSplit)
186{
187 CellCtlData* pCtlData = 0;
188
189 hwnd = CellWindowFromID(hwnd, lID);
190
191 if(!hwnd)
192 return 0;
193
194 pCtlData = (CellCtlData *)WinQueryWindowULong(hwnd, QWL_USER);
195
196 if(!pCtlData)
197 return 0;
198
199 if(!(pCtlData->lType & CELL_FIXED))
200 {
201 pCtlData->lSplit = lNewSplit;
202 if(pCtlData->lSplit > CELL_TOP_LIMIT)
203 pCtlData->lSplit = CELL_TOP_LIMIT;
204
205 if(pCtlData->lSplit < CELL_BOTTOM_LIMIT)
206 pCtlData->lSplit = CELL_BOTTOM_LIMIT;
207
208 WinSendMsg(hwnd, WM_UPDATEFRAME, 0, 0);
209 }
210
211 return pCtlData->lSplit;
212}
213
214LONG GetSplitType(HWND hwnd, LONG lID)
215{
216 CellCtlData* pCtlData = 0;
217
218 hwnd = CellWindowFromID(hwnd, lID);
219
220 if(!hwnd)
221 return 0;
222
223 pCtlData = (CellCtlData *)WinQueryWindowULong(hwnd, QWL_USER);
224
225 if(!pCtlData)
226 return 0;
227
228 return (pCtlData->lType & (CELL_VSPLIT | CELL_HSPLIT | CELL_SWAP));
229}
230
231void SetSplitType(HWND hwnd, LONG lID, LONG lNewSplit)
232{
233 CellCtlData* pCtlData = 0;
234
235 hwnd = CellWindowFromID(hwnd, lID);
236
237 if(!hwnd)
238 return;
239
240 pCtlData = (CellCtlData *)WinQueryWindowULong(hwnd, QWL_USER);
241
242 if(!pCtlData)
243 return;
244
245 pCtlData->lType &= ~(CELL_VSPLIT | CELL_HSPLIT);
246 pCtlData->lType |= lNewSplit & (CELL_VSPLIT | CELL_HSPLIT);
247
248 if(lNewSplit & CELL_SWAP) //Swap required?
249 {
250 if(!(pCtlData->lType & CELL_SWAP)) //Not swapped yet
251 {
252 //Swap subwindows
253 HWND hwndTmp = pCtlData->hwndPanel1;
254 pCtlData->hwndPanel1 = pCtlData->hwndPanel2;
255 pCtlData->hwndPanel2 = hwndTmp;
256 }
257
258 pCtlData->lType |= CELL_SWAP;
259 }
260 else
261 {
262 if(pCtlData->lType & CELL_SWAP) //Already swapped
263 {
264 //Restore original state
265 HWND hwndTmp = pCtlData->hwndPanel1;
266 pCtlData->hwndPanel1 = pCtlData->hwndPanel2;
267 pCtlData->hwndPanel2 = hwndTmp;
268 }
269
270 pCtlData->lType &= ~CELL_SWAP;
271 }
272}
273
274/* Function: CountControls
275** Abstract: calculates number of additional controls in cell window
276*/
277
278USHORT CountControls(CellCtlData * pCtlData)
279{
280 USHORT itemCount = 0;
281 CellTb *pCellTb = 0;
282
283 if(pCtlData->hwndPanel1 && !(pCtlData->lType & CELL_HIDE_1))
284 itemCount++;
285
286 if(pCtlData->hwndPanel2 && !(pCtlData->lType & CELL_HIDE_2))
287 itemCount++;
288
289 pCellTb = pCtlData->pCellTb;
290
291 while(pCellTb)
292 {
293 LONG lFlags = (LONG)WinSendMsg(pCellTb->hWnd,
294 TKM_QUERY_FLAGS, 0, 0);
295 if(lFlags & TB_ATTACHED)
296 itemCount++;
297
298 pCellTb = pCellTb->pNext;
299 }
300
301 return itemCount;
302}
303
304/* Function: CellProc
305** Abstract: Subclass procedure for frame window
306*/
307
308MRESULT EXPENTRY CellProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
309{
310 CellCtlData* pCtlData = 0;
311 CellTb *pCellTb = 0;
312 ULONG itemCount;
313
314 pCtlData = (CellCtlData *)WinQueryWindowULong(hwnd, QWL_USER);
315
316 if(!pCtlData)
317 {
318 return 0;
319 }
320 switch(msg)
321 {
322 case WM_ADJUSTWINDOWPOS:
323 {
324 HWND hwndBehind;
325 PSWP pSwp;
326
327 pCellTb = pCtlData->pCellTb;
328 pSwp = (PSWP)mp1;
329
330 if(!(pSwp->fl & SWP_ZORDER) || !pCellTb)
331 break;
332
333 hwndBehind = pSwp->hwndInsertBehind;
334
335 while(pCellTb)
336 {
337 LONG lFlags = (LONG)WinSendMsg(pCellTb->hWnd,
338 TKM_QUERY_FLAGS, 0, 0);
339 if(!(lFlags & TB_ATTACHED))
340 {
341
342 WinSetWindowPos (pCellTb->hWnd,
343 hwndBehind,
344 0, 0, 0, 0, SWP_ZORDER);
345
346 hwndBehind = pCellTb->hWnd;
347 }
348
349 pCellTb = pCellTb->pNext;
350 }
351 pSwp->hwndInsertBehind = hwndBehind;
352 }
353 break;
354
355 case TKM_SEARCH_PARENT:
356 {
357 HWND hwndRC;
358
359 if(WinQueryWindowUShort(hwnd, QWS_ID) == (ULONG)mp1)
360 return MRFROMSHORT(FALSE);
361
362 if(WinQueryWindowUShort(pCtlData->hwndPanel1, QWS_ID)
363 == (ULONG)mp1)
364 return (MPARAM)hwnd;
365
366 hwndRC = (HWND)WinSendMsg(pCtlData->hwndPanel1,
367 TKM_SEARCH_PARENT,
368 mp1, 0);
369 if(hwndRC)
370 return (MPARAM)hwndRC;
371
372 if(WinQueryWindowUShort(pCtlData->hwndPanel2, QWS_ID)
373 == (ULONG)mp1)
374 return (MPARAM)hwnd;
375
376 hwndRC = (HWND)WinSendMsg(pCtlData->hwndPanel2,
377 TKM_SEARCH_PARENT,
378 mp1, 0);
379 if(hwndRC)
380 return (MPARAM)hwndRC;
381
382 }
383 return MRFROMSHORT(FALSE);
384
385 case TKM_SEARCH_ID:
386 {
387 HWND hwndRC;
388 pCellTb = pCtlData->pCellTb;
389
390 while(pCellTb)
391 {
392 if(WinQueryWindowUShort(pCellTb->hWnd, QWS_ID)
393 == (ULONG)mp1)
394 return (MPARAM)pCellTb->hWnd;
395
396 hwndRC = (HWND)WinSendMsg(pCellTb->hWnd,
397 TKM_SEARCH_ID,
398 mp1, 0);
399
400 if(hwndRC)
401 return (MPARAM)hwndRC;
402
403 pCellTb = pCellTb->pNext;
404 }
405
406 if(WinQueryWindowUShort(hwnd, QWS_ID) == (ULONG)mp1)
407 return (MPARAM)hwnd;
408
409 if(WinQueryWindowUShort(pCtlData->hwndPanel1, QWS_ID)
410 == (ULONG)mp1)
411 return (MPARAM)pCtlData->hwndPanel1;
412
413 hwndRC = (HWND)WinSendMsg(pCtlData->hwndPanel1,
414 TKM_SEARCH_ID,
415 mp1, 0);
416 if(hwndRC)
417 return (MPARAM)hwndRC;
418
419 if(WinQueryWindowUShort(pCtlData->hwndPanel2, QWS_ID)
420 == (ULONG)mp1)
421 return (MPARAM)pCtlData->hwndPanel2;
422
423 hwndRC = (HWND)WinSendMsg(pCtlData->hwndPanel2,
424 TKM_SEARCH_ID,
425 mp1, 0);
426 if(hwndRC)
427 return (MPARAM)hwndRC;
428
429 }
430 return MRFROMSHORT(FALSE);
431
432 case WM_QUERYFRAMECTLCOUNT:
433 {
434 itemCount = (ULONG)pCtlData->pOldProc(hwnd, msg, mp1, mp2);
435 itemCount += CountControls(pCtlData); /* Add new controls */
436 }
437 return MRFROMSHORT(itemCount);
438
439 case WM_FORMATFRAME:
440 {
441 PSWP pSWP = 0;
442 USHORT usClient = 0;
443 USHORT itemCount2;
444 SWP swp;
445 HWND hClient = HWND_TOP;
446
447 itemCount = (ULONG)pCtlData->pOldProc(hwnd, msg, mp1, mp2);
448 itemCount2 = CountControls(pCtlData);
449
450 if(!itemCount2 || itemCount < 1)
451 return MRFROMSHORT(itemCount);
452
453 pSWP = (PSWP)PVOIDFROMMP(mp1);
454
455 usClient = itemCount - 1;
456
457 hClient = pSWP[usClient].hwnd;
458
459 /*
460 ** Cutting client window.
461 ** If there are any attached toolbars, cut client window
462 ** regarding to attachment type
463 */
464
465 /* Toolbars attached to top and bottom sides */
466
467 pCellTb = pCtlData->pCellTb;
468
469 while(pCellTb)
470 {
471 POINTL ptlSize;
472 LONG lFlags = (LONG)WinSendMsg(pCellTb->hWnd,
473 TKM_QUERY_FLAGS, 0, 0);
474
475 if(!(lFlags & TB_ATTACHED))
476 {
477 pCellTb = pCellTb->pNext;
478 continue;
479 }
480
481 RecalcTbDimensions(pCellTb->hWnd, &ptlSize);
482
483 switch(lFlags & TB_ATTACHED)
484 {
485 case TB_ATTACHED_TP:
486 pSWP[itemCount].x = pSWP[usClient].x;
487 pSWP[itemCount].y = pSWP[usClient].y +
488 pSWP[usClient].cy - ptlSize.y;
489 pSWP[itemCount].cx = pSWP[usClient].cx;
490 pSWP[itemCount].cy = ptlSize.y;
491 pSWP[itemCount].fl = SWP_SIZE |
492 SWP_MOVE |
493 SWP_SHOW;
494
495 pSWP[itemCount].hwnd = pCellTb->hWnd;
496 pSWP[itemCount].hwndInsertBehind = hClient;
497 hClient = pSWP[itemCount].hwnd;
498
499 pSWP[usClient].cy -= ptlSize.y;
500 itemCount++;
501 break;
502
503 case TB_ATTACHED_BT:
504 pSWP[itemCount].x = pSWP[usClient].x;
505 pSWP[itemCount].y = pSWP[usClient].y;
506 pSWP[itemCount].cx = pSWP[usClient].cx;
507 pSWP[itemCount].cy = ptlSize.y;
508 pSWP[itemCount].fl = SWP_SIZE | SWP_MOVE | SWP_SHOW;
509
510 pSWP[itemCount].hwnd = pCellTb->hWnd;
511 pSWP[itemCount].hwndInsertBehind = hClient;
512 hClient = pSWP[itemCount].hwnd;
513
514 pSWP[usClient].cy -= ptlSize.y;
515 pSWP[usClient].y += ptlSize.y;
516 itemCount++;
517 break;
518 }
519 pCellTb = pCellTb->pNext;
520 }
521
522 /*Toolbars attached to left and right sides*/
523
524 pCellTb = pCtlData->pCellTb;
525
526 while(pCellTb)
527 {
528 POINTL ptlSize;
529 LONG lFlags = (LONG)WinSendMsg(pCellTb->hWnd,
530 TKM_QUERY_FLAGS, 0, 0);
531
532 if(!(lFlags & TB_ATTACHED))
533 {
534 pCellTb = pCellTb->pNext;
535 continue;
536 }
537
538 RecalcTbDimensions(pCellTb->hWnd, &ptlSize);
539
540 switch(lFlags & TB_ATTACHED)
541 {
542 case TB_ATTACHED_LT:
543 pSWP[itemCount].x = pSWP[usClient].x;
544 pSWP[itemCount].y = pSWP[usClient].y;
545 pSWP[itemCount].cx = ptlSize.x;
546 pSWP[itemCount].cy = pSWP[usClient].cy;
547 pSWP[itemCount].fl = SWP_SIZE | SWP_MOVE | SWP_SHOW;
548 pSWP[itemCount].hwnd = pCellTb->hWnd;
549 pSWP[itemCount].hwndInsertBehind = hClient;
550 hClient = pSWP[itemCount].hwnd;
551
552 pSWP[usClient].cx -= ptlSize.x;
553 pSWP[usClient].x += ptlSize.x;
554 itemCount++;
555 break;
556
557 case TB_ATTACHED_RT:
558 pSWP[itemCount].x = pSWP[usClient].x +
559 pSWP[usClient].cx - ptlSize.x;
560 pSWP[itemCount].y = pSWP[usClient].y;
561 pSWP[itemCount].cx = ptlSize.x;
562 pSWP[itemCount].cy = pSWP[usClient].cy;
563 pSWP[itemCount].fl = SWP_SIZE | SWP_MOVE | SWP_SHOW;
564 pSWP[itemCount].hwnd = pCellTb->hWnd;
565 pSWP[itemCount].hwndInsertBehind = hClient;
566 hClient = pSWP[itemCount].hwnd;
567
568 pSWP[usClient].cx -= ptlSize.x;
569 itemCount++;
570 break;
571 }
572 pCellTb = pCellTb->pNext;
573 }
574
575 /*
576 ** Placing panels.
577 ** Remember client rect for future use
578 ** They will save time when we start moving splitbar
579 */
580
581 pCtlData->rclBnd.xLeft = pSWP[usClient].x;
582 pCtlData->rclBnd.xRight = pSWP[usClient].x + pSWP[usClient].cx;
583 pCtlData->rclBnd.yTop = pSWP[usClient].y + pSWP[usClient].cy;
584 pCtlData->rclBnd.yBottom = pSWP[usClient].y;
585
586 if(!pCtlData->hwndPanel1 || !pCtlData->hwndPanel2 ||
587 (pCtlData->lType & CELL_HIDE))
588 {
589 /*
590 **single subwindow;
591 **In this case we don't need a client window,
592 **because of lack of splitbar.
593 **Just copy all data from pSWP[usClient]
594 **and replace some part of it
595 */
596
597 pSWP[itemCount] = pSWP[usClient];
598 pSWP[itemCount].fl |= SWP_MOVE | SWP_SIZE;
599 pSWP[itemCount].hwndInsertBehind = HWND_TOP;
600 pSWP[usClient].cy = 0;
601
602 pSWP[itemCount].hwnd = 0;
603
604 if(pCtlData->hwndPanel1 && !(pCtlData->lType & CELL_HIDE_1))
605 pSWP[itemCount].hwnd = pCtlData->hwndPanel1;
606
607 if(pCtlData->hwndPanel2 && !(pCtlData->lType & CELL_HIDE_2))
608 pSWP[itemCount].hwnd = pCtlData->hwndPanel2;
609
610 /* Increase number of controls */
611
612 if(pSWP[itemCount].hwnd)
613 {
614 pSWP[itemCount].hwndInsertBehind = hClient;
615 hClient = pSWP[itemCount].hwnd;
616 itemCount++;
617 }
618 }
619 else
620 {
621 USHORT usPanel1 = itemCount;
622 USHORT usPanel2 = itemCount + 1;
623 USHORT usWidth1 = 0;
624 USHORT usWidth2 = 0;
625
626 /* Just like case of one panel */
627
628 pSWP[usPanel1] = pSWP[usClient];
629 pSWP[usPanel2] = pSWP[usClient];
630
631 pSWP[usPanel1].fl |= SWP_MOVE | SWP_SIZE;
632 pSWP[usPanel2].fl |= SWP_MOVE | SWP_SIZE;
633
634 pSWP[usPanel1].hwndInsertBehind = hClient;
635 pSWP[usPanel2].hwndInsertBehind = pCtlData->hwndPanel1;
636
637 pSWP[usPanel1].hwnd = pCtlData->hwndPanel1;
638 pSWP[usPanel2].hwnd = pCtlData->hwndPanel2;
639
640 hClient = pCtlData->hwndPanel2;
641
642 if(pCtlData->lType & CELL_VSPLIT)
643 {
644 if((pCtlData->lType & CELL_FIXED) &&
645 (pCtlData->lType & (CELL_SIZE1 | CELL_SIZE2)) &&
646 (pCtlData->lSize > 0))
647 {
648 /* Case of fixed panel with exact size */
649
650 if(pCtlData->lType & CELL_SIZE1)
651 {
652 usWidth1 = pCtlData->lSize;
653 usWidth2 = pSWP[usClient].cx - usWidth1;
654 }
655 else
656 {
657 usWidth2 = pCtlData->lSize;
658 usWidth1 = pSWP[usClient].cx - usWidth2;
659 }
660 }
661 else
662 {
663 usWidth1 = (pSWP[usClient].cx * pCtlData->lSplit)
664 / 100;
665 usWidth2 = pSWP[usClient].cx - usWidth1;
666 }
667
668 if(pCtlData->lType & CELL_SPLITBAR)
669 {
670 if(!(pCtlData->lType & CELL_SIZE1))
671 usWidth2 -= SPLITBAR_WIDTH;
672 else
673 usWidth1 -= SPLITBAR_WIDTH;
674
675 pSWP[usClient].cx = SPLITBAR_WIDTH;
676 pSWP[usClient].x = pSWP[usClient].x + usWidth1;
677 }
678 else
679 {
680 pSWP[usClient].cx = 0;
681 pSWP[usClient].cy = 0;
682 }
683
684 pSWP[usPanel1].cx = usWidth1;
685 pSWP[usPanel2].x += usWidth1 + pSWP[usClient].cx;
686 pSWP[usPanel2].cx = usWidth2;
687 } /* if(pCtlData->lType & CELL_VSPLIT) */
688 else
689 {
690 if((pCtlData->lType & CELL_FIXED) &&
691 (pCtlData->lType & (CELL_SIZE1 | CELL_SIZE2)) &&
692 (pCtlData->lSize > 0))
693 {
694 /* Case of fixed panel with exact size */
695
696 if(pCtlData->lType & CELL_SIZE1)
697 {
698 usWidth1 = pCtlData->lSize;
699 usWidth2 = pSWP[usClient].cy - usWidth1;
700 }
701 else
702 {
703 usWidth2 = pCtlData->lSize;
704 usWidth1 = pSWP[usClient].cy - usWidth2;
705 }
706 }
707 else
708 {
709 usWidth1 = (pSWP[usClient].cy * pCtlData->lSplit)
710 / 100;
711 usWidth2 = pSWP[usClient].cy - usWidth1;
712 }
713
714 if(pCtlData->lType & CELL_SPLITBAR)
715 {
716 if(!(pCtlData->lType & CELL_SIZE1))
717 usWidth2 -= SPLITBAR_WIDTH;
718 else
719 usWidth1 -= SPLITBAR_WIDTH;
720 pSWP[usClient].cy = SPLITBAR_WIDTH;
721 pSWP[usClient].y = pSWP[usClient].y + usWidth1;
722 }
723 else
724 {
725 pSWP[usClient].cx = 0;
726 pSWP[usClient].cy = 0;
727 }
728
729 pSWP[usPanel1].cy = usWidth1;
730 pSWP[usPanel2].y += usWidth1 + pSWP[usClient].cy;
731 pSWP[usPanel2].cy = usWidth2;
732 }
733
734 itemCount += 2;
735 }
736 }
737 return MRFROMSHORT(itemCount);
738 }
739 return pCtlData->pOldProc(hwnd, msg, mp1, mp2);
740}
741
742/* Function: CellClientProc
743** Abstract: Window procedure for Cell Client Window Class (splitbar)
744*/
745
746MRESULT EXPENTRY CellClientProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
747{
748 HWND hwndFrame = 0;
749 CellCtlData *pCtlData = 0;
750
751 hwndFrame = WinQueryWindow(hwnd, QW_PARENT);
752
753 if(hwndFrame)
754 pCtlData = (CellCtlData *)WinQueryWindowULong(hwndFrame, QWL_USER);
755
756 if(!hwndFrame || !pCtlData)
757 return WinDefWindowProc(hwnd, msg, mp1, mp2);
758
759 switch (msg)
760 {
761 case WM_ACTIVATE:
762 case WM_SETFOCUS:
763 return (MRESULT)(FALSE);
764
765 case WM_PAINT:
766 {
767 HPS hpsPaint;
768 RECTL rclPaint;
769 POINTL ptlStart[SPLITBAR_WIDTH];
770 POINTL ptlEnd[SPLITBAR_WIDTH];
771 PLONG pColorTable;
772 USHORT i;
773
774 hpsPaint = WinBeginPaint(hwnd, 0, 0);
775 WinQueryWindowRect(hwnd, &rclPaint);
776
777 if(pCtlData->lType & CELL_VSPLIT)
778 {
779 for(i = 0; i < SPLITBAR_WIDTH; i++)
780 {
781 ptlStart[i].x = rclPaint.xLeft + i;
782 ptlStart[i].y = rclPaint.yTop;
783
784 ptlEnd[i].x = rclPaint.xLeft + i;
785 ptlEnd[i].y = rclPaint.yBottom;
786 }
787 pColorTable = (pCtlData->lType & CELL_FIXED)
788 ? lColor
789 : lColor2;
790 }
791 else
792 {
793 for(i = 0; i < SPLITBAR_WIDTH; i++)
794 {
795 ptlStart[i].x = rclPaint.xLeft;
796 ptlStart[i].y = rclPaint.yBottom + i;
797
798 ptlEnd[i].x = rclPaint.xRight;
799 ptlEnd[i].y = rclPaint.yBottom + i;
800 }
801 pColorTable = (pCtlData->lType & CELL_FIXED)
802 ? lColor2
803 : lColor;
804 }
805
806 for(i = 0; i < SPLITBAR_WIDTH; i++)
807 {
808 GpiSetColor( hpsPaint, pColorTable[i]);
809 GpiMove(hpsPaint, &ptlStart[i]);
810 GpiLine(hpsPaint, &ptlEnd[i]);
811 }
812 WinEndPaint(hpsPaint);
813 }
814 return MRFROMSHORT(FALSE);
815
816 case WM_MOUSEMOVE:
817 {
818 if(pCtlData->lType & CELL_FIXED)
819 break;
820
821 if(pCtlData->lType & CELL_VSPLIT)
822 WinSetPointer(HWND_DESKTOP,
823 WinQuerySysPointer(HWND_DESKTOP,
824 SPTR_SIZEWE,
825 FALSE));
826 else
827 WinSetPointer(HWND_DESKTOP,
828 WinQuerySysPointer(HWND_DESKTOP,
829 SPTR_SIZENS,
830 FALSE));
831 }
832 return MRFROMSHORT(FALSE);
833
834 case WM_BUTTON1DOWN:
835 {
836 APIRET rc;
837 RECTL rclFrame;
838 RECTL rclBounds;
839
840 if(pCtlData->lType & CELL_FIXED)
841 break;
842
843 WinQueryWindowRect(hwnd, &rclFrame);
844
845 rclBounds = pCtlData->rclBnd;
846
847 WinMapWindowPoints(hwndFrame, HWND_DESKTOP,
848 (PPOINTL)&rclBounds, 2);
849
850 rc = TrackRectangle(hwnd, &rclFrame, &rclBounds);
851
852 if(rc == TRUE)
853 {
854 USHORT usNewRB;
855 USHORT usSize;
856
857 if(pCtlData->lType & CELL_VSPLIT)
858 {
859 usNewRB = rclFrame.xLeft
860 - rclBounds.xLeft;
861 usSize = rclBounds.xRight
862 - rclBounds.xLeft;
863 }
864 else
865 {
866 usNewRB = rclFrame.yBottom
867 - rclBounds.yBottom;
868 usSize = rclBounds.yTop
869 - rclBounds.yBottom;
870 }
871
872 pCtlData->lSplit = (usNewRB * 100)/usSize;
873 if(pCtlData->lSplit > CELL_TOP_LIMIT)
874 pCtlData->lSplit = CELL_TOP_LIMIT;
875
876 if(pCtlData->lSplit < CELL_BOTTOM_LIMIT)
877 pCtlData->lSplit = CELL_BOTTOM_LIMIT;
878
879 WinSendMsg(hwndFrame, WM_UPDATEFRAME, 0, 0);
880 }
881 }
882 return MRFROMSHORT(FALSE);
883
884 case WM_BUTTON2DOWN:
885
886 if(pCtlData->lType & CELL_FIXED)
887 break;
888
889 {
890 ULONG lType = pCtlData->lType & (CELL_VSPLIT | CELL_HSPLIT);
891
892 pCtlData->lType &= ~(CELL_VSPLIT | CELL_HSPLIT);
893
894 if(lType & CELL_VSPLIT)
895 {
896 pCtlData->lType |= CELL_HSPLIT;
897 }
898 else
899 {
900 pCtlData->lType |= CELL_VSPLIT;
901 }
902
903 //Swap subwindows
904
905 if(lType & CELL_VSPLIT)
906 {
907 HWND hwndTmp = pCtlData->hwndPanel1;
908 pCtlData->hwndPanel1 = pCtlData->hwndPanel2;
909 pCtlData->hwndPanel2 = hwndTmp;
910
911 pCtlData->lType ^= CELL_SWAP;
912 }
913
914 if(pCtlData->lType & CELL_HIDE_1)
915 {
916 pCtlData->lType &= ~CELL_HIDE_1;
917 pCtlData->lType |= CELL_HIDE_2;
918 }
919 else
920 {
921 if(pCtlData->lType & CELL_HIDE_2)
922 {
923 pCtlData->lType &= ~CELL_HIDE_2;
924 pCtlData->lType |= CELL_HIDE_1;
925 }
926 }
927
928 if(pCtlData->lType & CELL_SIZE1)
929 {
930 pCtlData->lType &= ~CELL_SIZE1;
931 pCtlData->lType |= CELL_SIZE2;
932 }
933 else
934 {
935 if(pCtlData->lType & CELL_SIZE2)
936 {
937 pCtlData->lType &= ~CELL_SIZE2;
938 pCtlData->lType |= CELL_SIZE1;
939 }
940 }
941
942 WinSendMsg(hwndFrame, WM_UPDATEFRAME, 0, 0);
943 }
944 return MRFROMSHORT(FALSE);
945 }
946 return WinDefWindowProc(hwnd, msg, mp1, mp2);
947}
948
949
950/* Function: CreateCell
951** Abstract: Creates a subwindows tree for a given CellDef for a WPS folder
952** Note: If hWndOwner == NULLHANDLE, and first CellDef is frame,
953** all subwindows will have this frame window as Owner.
954*/
955
956HWND createCellForFolder(CellDef* pCell, HWND hWndParent, HWND hWndOwner, HWND hwndFolder, WPObject * wpObject)
957{
958 HWND hwndFrame = NULLHANDLE;
959 CellCtlData* pCtlData = 0;
960 WindowCellCtlData * pWCtlData = 0;
961
962 if(!pCell)
963 return hwndFrame;
964
965 switch(pCell->lType & (CELL_VSPLIT | CELL_HSPLIT | CELL_WINDOW))
966 {
967 case CELL_WINDOW:
968 hwndFrame = WinCreateWindow(hWndParent,
969 pCell->pszClass,
970 pCell->pszName,
971 pCell->ulStyle,
972 0, 0, 0, 0,
973 hWndOwner,
974 HWND_TOP,
975 pCell->ulID,
976 NULL,
977 NULL);
978
979 if(pCell->pClassProc && hwndFrame)
980 {
981 pWCtlData = (WindowCellCtlData *)
982 malloc(sizeof(WindowCellCtlData));
983 if(!pWCtlData)
984 return hwndFrame;
985
986 memset(pWCtlData, 0, sizeof(WindowCellCtlData));
987 pWCtlData->pOldProc = WinSubclassWindow(hwndFrame,
988 pCell->pClassProc);
989 WinSetWindowULong(hwndFrame, QWL_USER, (ULONG)pWCtlData);
990 }
991
992 break;
993
994 case CELL_HSPLIT:
995 case CELL_VSPLIT:
996
997 pCtlData = (CellCtlData *)malloc(sizeof(CellCtlData));
998 if(!pCtlData)
999 return hwndFrame;
1000
1001 memset(pCtlData, 0, sizeof(CellCtlData));
1002
1003 pCtlData->lType = pCell->lType & (CELL_SPLIT_MASK | CELL_HIDE);
1004 pCtlData->lSize = (pCell->lType & (CELL_SIZE1
1005 | CELL_SIZE2
1006 | CELL_FIXED))
1007 ? pCell->lSize
1008 : 0;
1009
1010 pCtlData->lSplit = 50;
1011
1012 switch(pCell->lType & CELL_SPLIT_REL)
1013 {
1014 case CELL_SPLIT10x90: pCtlData->lSplit = 10; break;
1015 case CELL_SPLIT20x80: pCtlData->lSplit = 20; break;
1016 case CELL_SPLIT30x70: pCtlData->lSplit = 30; break;
1017 case CELL_SPLIT40x60: pCtlData->lSplit = 40; break;
1018 case CELL_SPLIT50x50: pCtlData->lSplit = 50; break;
1019 case CELL_SPLIT60x40: pCtlData->lSplit = 60; break;
1020 case CELL_SPLIT70x30: pCtlData->lSplit = 70; break;
1021 case CELL_SPLIT80x20: pCtlData->lSplit = 80; break;
1022 case CELL_SPLIT90x10: pCtlData->lSplit = 90; break;
1023 }
1024
1025 hwndFrame = WinCreateStdWindow(hWndParent,
1026 WS_VISIBLE,
1027 &pCell->ulStyle,
1028 CELL_CLIENT,
1029 "",
1030 0L, 0,
1031 pCell->ulID,
1032 &pCtlData->hwndSplitbar);
1033 if(!hwndFrame) {
1034 free(pCtlData);
1035 return hwndFrame;
1036 }
1037
1038 WinSetOwner(hwndFrame, hWndOwner);
1039
1040 if(pCell->pClassProc)
1041 pCtlData->pOldProc = WinSubclassWindow(hwndFrame,
1042 pCell->pClassProc);
1043 else
1044 pCtlData->pOldProc = WinSubclassWindow(hwndFrame, CellProc);
1045
1046 if(pCell->pClientClassProc)
1047 {
1048 pWCtlData = (WindowCellCtlData *)
1049 malloc(sizeof(WindowCellCtlData));
1050 if(!pWCtlData) {
1051 return hwndFrame;
1052 }
1053 memset(pWCtlData, 0, sizeof(WindowCellCtlData));
1054
1055 pWCtlData->pOldProc = WinSubclassWindow(pCtlData->hwndSplitbar,
1056 pCell->pClientClassProc);
1057 WinSetWindowULong(pCtlData->hwndSplitbar,
1058 QWL_USER,
1059 (ULONG)pWCtlData);
1060 }
1061 if(!hWndOwner)
1062 hWndOwner = hwndFrame;
1063 else
1064 WinSetOwner(pCtlData->hwndSplitbar, hWndOwner);
1065
1066 pCtlData->hwndPanel1 = createCellForFolder(pCell->pPanel1,
1067 hwndFrame,
1068 hWndOwner,
1069 hwndFolder,
1070 wpObject);
1071 pCtlData->hwndPanel2 = createCellForFolder(pCell->pPanel2,
1072 hwndFrame,
1073 hWndOwner,
1074 hwndFolder,
1075 wpObject);
1076 WinSetWindowULong(hwndFrame, QWL_USER, (ULONG)pCtlData);
1077 break;
1078 }
1079
1080 if(pWCtlData) {
1081 pWCtlData->hwndFolder=hwndFolder;
1082 pWCtlData->wpObject=wpObject;
1083 }
1084 return hwndFrame;
1085}
1086
1087
1088/* Function: CreateCell
1089** Abstract: Creates a subwindows tree for a given CellDef
1090** Note: If hWndOwner == NULLHANDLE, and first CellDef is frame,
1091** all subwindows will have this frame window as Owner.
1092*/
1093
1094HWND CreateCell(CellDef* pCell, HWND hWndParent, HWND hWndOwner)
1095{
1096 HWND hwndFrame = NULLHANDLE;
1097 CellCtlData* pCtlData = 0;
1098 WindowCellCtlData * pWCtlData = 0;
1099
1100 if(!pCell)
1101 return hwndFrame;
1102
1103 switch(pCell->lType & (CELL_VSPLIT | CELL_HSPLIT | CELL_WINDOW))
1104 {
1105 case CELL_WINDOW:
1106 hwndFrame = WinCreateWindow(hWndParent,
1107 pCell->pszClass,
1108 pCell->pszName,
1109 pCell->ulStyle,
1110 0, 0, 0, 0,
1111 hWndOwner,
1112 HWND_TOP,
1113 pCell->ulID,
1114 NULL,
1115 NULL);
1116
1117 if(pCell->pClassProc && hwndFrame)
1118 {
1119 pWCtlData = (WindowCellCtlData *)
1120 malloc(sizeof(WindowCellCtlData));
1121 if(!pWCtlData)
1122 return hwndFrame;
1123
1124 memset(pWCtlData, 0, sizeof(WindowCellCtlData));
1125 pWCtlData->pOldProc = WinSubclassWindow(hwndFrame,
1126 pCell->pClassProc);
1127 WinSetWindowULong(hwndFrame, QWL_USER, (ULONG)pWCtlData);
1128 }
1129 break;
1130
1131 case CELL_HSPLIT:
1132 case CELL_VSPLIT:
1133
1134 pCtlData = (CellCtlData *)malloc(sizeof(CellCtlData));
1135 if(!pCtlData)
1136 return hwndFrame;
1137
1138 memset(pCtlData, 0, sizeof(CellCtlData));
1139
1140 pCtlData->lType = pCell->lType & (CELL_SPLIT_MASK | CELL_HIDE);
1141 pCtlData->lSize = (pCell->lType & (CELL_SIZE1
1142 | CELL_SIZE2
1143 | CELL_FIXED))
1144 ? pCell->lSize
1145 : 0;
1146
1147 pCtlData->lSplit = 50;
1148
1149 switch(pCell->lType & CELL_SPLIT_REL)
1150 {
1151 case CELL_SPLIT10x90: pCtlData->lSplit = 10; break;
1152 case CELL_SPLIT20x80: pCtlData->lSplit = 20; break;
1153 case CELL_SPLIT30x70: pCtlData->lSplit = 30; break;
1154 case CELL_SPLIT40x60: pCtlData->lSplit = 40; break;
1155 case CELL_SPLIT50x50: pCtlData->lSplit = 50; break;
1156 case CELL_SPLIT60x40: pCtlData->lSplit = 60; break;
1157 case CELL_SPLIT70x30: pCtlData->lSplit = 70; break;
1158 case CELL_SPLIT80x20: pCtlData->lSplit = 80; break;
1159 case CELL_SPLIT90x10: pCtlData->lSplit = 90; break;
1160 }
1161
1162 hwndFrame = WinCreateStdWindow(hWndParent,
1163 WS_VISIBLE,
1164 &pCell->ulStyle,
1165 CELL_CLIENT,
1166 "",
1167 0L, 0,
1168 pCell->ulID,
1169 &pCtlData->hwndSplitbar);
1170 WinSetOwner(hwndFrame, hWndOwner);
1171
1172 if(pCell->pClassProc)
1173 pCtlData->pOldProc = WinSubclassWindow(hwndFrame,
1174 pCell->pClassProc);
1175 else
1176 pCtlData->pOldProc = WinSubclassWindow(hwndFrame, CellProc);
1177
1178 if(pCell->pClientClassProc)
1179 {
1180 pWCtlData = (WindowCellCtlData *)
1181 malloc(sizeof(WindowCellCtlData));
1182 if(!pWCtlData)
1183 return hwndFrame;
1184
1185 memset(pWCtlData, 0, sizeof(WindowCellCtlData));
1186
1187 pWCtlData->pOldProc = WinSubclassWindow(pCtlData->hwndSplitbar,
1188 pCell->pClientClassProc);
1189 WinSetWindowULong(pCtlData->hwndSplitbar,
1190 QWL_USER,
1191 (ULONG)pWCtlData);
1192 }
1193
1194 if(!hWndOwner)
1195 hWndOwner = hwndFrame;
1196 else
1197 WinSetOwner(pCtlData->hwndSplitbar, hWndOwner);
1198
1199 pCtlData->hwndPanel1 = CreateCell(pCell->pPanel1,
1200 hwndFrame,
1201 hWndOwner);
1202 pCtlData->hwndPanel2 = CreateCell(pCell->pPanel2,
1203 hwndFrame,
1204 hWndOwner);
1205
1206 WinSetWindowULong(hwndFrame, QWL_USER, (ULONG)pCtlData);
1207 break;
1208 }
1209
1210 return hwndFrame;
1211}
1212
1213
1214
1215/*****************************************************************************
1216** Toolbar implementation
1217*/
1218
1219/* Function: CreateTb
1220** Abstract: Creates Toolbar for a gived TbDef
1221*/
1222
1223HWND CreateTb(TbDef* pTb, HWND hWndParent, HWND hWndOwner)
1224{
1225 SWP swp;
1226 HWND hwndClient;
1227 HWND hwndTb = NULLHANDLE;
1228 LONG lCount;
1229 POINTL ptlSize;
1230 POINTL ptlFSize;
1231 ULONG flCreate;
1232 TbCtlData *pTbCtlData;
1233 TbItemData *pTbItemData;
1234
1235 if(!pTb)
1236 return hwndTb;
1237
1238 for(lCount = 0; pTb->tbItems[lCount]; )
1239 lCount++;
1240
1241 pTbCtlData = (TbCtlData *)malloc(sizeof(TbCtlData) +
1242 sizeof(HWND) * lCount);
1243
1244 if(!pTbCtlData)
1245 return hwndTb;
1246
1247 pTbItemData = (TbItemData *)malloc(sizeof(TbItemData) * lCount);
1248
1249 if(!pTbItemData)
1250 {
1251 free(pTbCtlData);
1252 return hwndTb;
1253 }
1254
1255 memset(pTbCtlData, 0, sizeof(TbCtlData) +
1256 sizeof(HWND) * lCount);
1257
1258 memset(pTbItemData, 0, sizeof(TbItemData) * lCount);
1259
1260 pTbCtlData->lCount = lCount;
1261 pTbCtlData->bBubble = (pTb->lType & TB_BUBBLE) ? 1:0;
1262
1263 pTb->lType &= TB_ALLOWED;
1264
1265 /*
1266 **Some checks:
1267 ** if toolbar attached, they should be properly
1268 ** oriented. I.e. toolbar attached to top or
1269 ** bottom, can't be vertical.
1270 */
1271
1272 if(pTb->lType & (TB_ATTACHED_TP | TB_ATTACHED_BT))
1273 pTb->lType &= ~TB_VERTICAL;
1274
1275 pTbCtlData->lState = pTb->lType;
1276 pTbCtlData->hwndParent = hWndParent;
1277
1278 if(!(pTb->lType & TB_ATTACHED))
1279 hWndParent = HWND_DESKTOP;
1280
1281 if(pTb->lType & TB_ATTACHED)
1282 flCreate = FCF_BORDER | FCF_NOBYTEALIGN;
1283 else
1284 flCreate = FCF_DLGBORDER | FCF_NOBYTEALIGN;
1285
1286 hwndTb = WinCreateStdWindow(hWndParent,
1287 WS_CLIPCHILDREN |
1288 WS_CLIPSIBLINGS |
1289 WS_PARENTCLIP |
1290 0,
1291 &flCreate,
1292 TB_CLIENT,
1293 "",
1294 0L, 0,
1295 pTb->ulID,
1296 &hwndClient);
1297 if(!hwndTb)
1298 {
1299 free(pTbCtlData);
1300 free(pTbItemData);
1301 return hwndTb;
1302 }
1303
1304 ptlSize.x = (pTbCtlData->lState & TB_VERTICAL) ? 0 : HAND_SIZE;
1305 ptlSize.y = (pTbCtlData->lState & TB_VERTICAL) ? HAND_SIZE : 0;
1306
1307 for(lCount = 0; lCount < pTbCtlData->lCount; lCount++)
1308 {
1309 CHAR cButtText[256];
1310
1311 if(pTb->tbItems[lCount] == TB_SEPARATOR)
1312 pTbCtlData->hItems[lCount] =
1313 WinCreateWindow(hwndTb,
1314 TB_SEPCLASS,
1315 "",
1316 0,
1317 0, 0, TB_SEP_SIZE, TB_SEP_SIZE,
1318 hwndTb,
1319 HWND_TOP,
1320 pTb->tbItems[lCount],
1321 NULL,
1322 NULL);
1323 else
1324 {
1325 flCreate = BS_PUSHBUTTON | BS_BITMAP |
1326 BS_AUTOSIZE | BS_NOPOINTERFOCUS;
1327
1328 GenResIDStr(cButtText, pTb->tbItems[lCount]);
1329
1330 pTbCtlData->hItems[lCount] =
1331 WinCreateWindow(hwndTb,
1332 WC_BUTTON,
1333 cButtText,
1334 flCreate,
1335 -1, -1, -1, -1,
1336 hWndOwner,
1337 HWND_TOP,
1338 pTb->tbItems[lCount],
1339 NULL,
1340 NULL);
1341
1342 pTbItemData[lCount].pOldProc =
1343 WinSubclassWindow(pTbCtlData->hItems[lCount],
1344 BtProc);
1345
1346 WinSetWindowULong(pTbCtlData->hItems[lCount],
1347 QWL_USER,
1348 (ULONG)(&pTbItemData[lCount]));
1349 }
1350
1351 WinQueryWindowPos(pTbCtlData->hItems[lCount], &swp);
1352
1353 if(pTbCtlData->lState & TB_VERTICAL)
1354 {
1355 if(swp.cx > ptlSize.x)
1356 ptlSize.x = swp.cx;
1357 ptlSize.y += swp.cy;
1358 }
1359 else
1360 {
1361 if(swp.cy > ptlSize.y)
1362 ptlSize.y = swp.cy;
1363 ptlSize.x += swp.cx;
1364 }
1365 }
1366
1367 /*
1368 ** Now we have calculated client window size for toolbar
1369 ** Recalculate its proper size
1370 */
1371
1372 WinSendMsg(hwndTb, WM_QUERYBORDERSIZE, MPFROMP(&ptlFSize), 0);
1373 ptlSize.x += ptlFSize.x * 2;
1374 ptlSize.y += ptlFSize.y * 2;
1375
1376 pTbCtlData->pOldProc = WinSubclassWindow(hwndTb, TbProc);
1377 WinSetWindowULong(hwndTb, QWL_USER, (ULONG)pTbCtlData);
1378
1379 WinQueryWindowPos(hWndOwner, &swp);
1380
1381 WinSetWindowPos(hwndTb, 0, swp.x + HAND_SIZE/2, swp.y + HAND_SIZE/2,
1382 ptlSize.x, ptlSize.y, SWP_MOVE | SWP_SIZE | SWP_SHOW);
1383 return hwndTb;
1384}
1385
1386/* Function: BtProc
1387** Abstract: Subclass procedure for buttons
1388*/
1389
1390MRESULT EXPENTRY BtProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
1391{
1392 HWND hwndFrame = 0;
1393 TbCtlData *pTbCtlData;
1394 TbItemData *pTbItemData;
1395
1396 hwndFrame = WinQueryWindow(hwnd, QW_PARENT);
1397 pTbCtlData = (TbCtlData *)WinQueryWindowULong(hwndFrame,
1398 QWL_USER);
1399
1400 pTbItemData = (TbItemData *)WinQueryWindowULong(hwnd,
1401 QWL_USER);
1402 switch(msg)
1403 {
1404 case WM_TIMER:
1405 if (pTbCtlData->hwndBubble)
1406 {
1407 WinDestroyWindow(pTbCtlData->hwndBubble);
1408 pTbCtlData->hwndBubble = 0;
1409 WinStopTimer(hab, hwnd, 1);
1410 }
1411 break;
1412
1413 case WM_MOUSEMOVE:
1414
1415 if(!(pTbCtlData->lState & TB_BUBBLE))
1416 break;
1417
1418 if(!pTbCtlData->bBubble)
1419 break;
1420
1421 if(WinQueryActiveWindow(HWND_DESKTOP) != hwndFrame &&
1422 WinQueryActiveWindow(HWND_DESKTOP) != pTbCtlData->hwndParent)
1423 break;
1424
1425 if(pTbCtlData->hwndLast == hwnd)
1426 break;
1427
1428 if(pTbCtlData->hwndBubble)
1429 {
1430 WinDestroyWindow(pTbCtlData->hwndBubble);
1431 pTbCtlData->hwndBubble = 0;
1432 WinStopTimer(hab, pTbCtlData->hwndLast, 1);
1433 }
1434
1435 if(!pTbCtlData->hwndBubble)
1436 {
1437 HWND hwndBubbleClient;
1438 ULONG ulStyle = FCF_BORDER | FCF_NOBYTEALIGN;
1439 HPS hpsTemp = 0;
1440 LONG lHight;
1441 LONG lWidth;
1442 POINTL txtPointl[TXTBOX_COUNT];
1443 POINTL ptlWork = {0,0};
1444 ULONG ulColor = CLR_PALEGRAY;
1445
1446 pTbCtlData->hwndLast = hwnd;
1447 pTbCtlData->hwndBubble = WinCreateStdWindow(HWND_DESKTOP,
1448 0,
1449 &ulStyle,
1450 WC_STATIC,
1451 "",
1452 SS_TEXT |
1453 DT_LEFT |
1454 DT_VCENTER,
1455 NULLHANDLE,
1456 TB_BUBBLEID,
1457 &hwndBubbleClient);
1458
1459 WinSetPresParam(hwndBubbleClient,
1460 PP_FONTNAMESIZE,
1461 sizeof(ppFont),
1462 ppFont);
1463
1464
1465 WinSetPresParam(hwndBubbleClient,
1466 PP_BACKGROUNDCOLORINDEX,
1467 sizeof(ulColor),
1468 &ulColor);
1469
1470 if(!pTbItemData->cText[0])
1471 {
1472 WinLoadString(hab,
1473 0,
1474 WinQueryWindowUShort(hwnd, QWS_ID),
1475 sizeof(pTbItemData->cText),
1476 pTbItemData->cText);
1477 }
1478
1479 WinSetWindowText(hwndBubbleClient,
1480 pTbItemData->cText);
1481
1482 WinMapWindowPoints(hwnd, HWND_DESKTOP, &ptlWork, 1);
1483
1484 hpsTemp = WinGetPS(hwndBubbleClient);
1485 GpiQueryTextBox(hpsTemp,
1486 strlen(pTbItemData->cText),
1487 pTbItemData->cText,
1488 TXTBOX_COUNT,
1489 txtPointl);
1490
1491 WinReleasePS(hpsTemp);
1492
1493 lWidth = txtPointl[TXTBOX_TOPRIGHT].x -
1494 txtPointl[TXTBOX_TOPLEFT ].x +
1495 WinQuerySysValue(HWND_DESKTOP,
1496 SV_CYDLGFRAME) * 2;
1497
1498 lHight = txtPointl[TXTBOX_TOPLEFT ].y -
1499 txtPointl[TXTBOX_BOTTOMLEFT].y +
1500 WinQuerySysValue(HWND_DESKTOP,
1501 SV_CXDLGFRAME) * 2;
1502
1503 if(!(pTbCtlData->lState & TB_VERTICAL))
1504 ptlWork.y -= lHight;
1505 else
1506 {
1507 RECTL rclButton;
1508 WinQueryWindowRect(hwnd, &rclButton);
1509 ptlWork.x += rclButton.xRight - rclButton.xLeft;
1510 }
1511
1512 WinSetWindowPos(pTbCtlData->hwndBubble,
1513 HWND_TOP,
1514 ptlWork.x,
1515 ptlWork.y,
1516 lWidth,
1517 lHight,
1518 SWP_SIZE | SWP_MOVE | SWP_SHOW);
1519
1520 WinStartTimer(hab, hwnd, 1, 1500);
1521 }
1522 break;
1523 }
1524
1525 return pTbItemData->pOldProc(hwnd, msg, mp1, mp2);
1526}
1527
1528/* Function: TbProc
1529** Abstract: Subclass procedure for toolbar window
1530*/
1531
1532MRESULT EXPENTRY TbProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
1533{
1534 TbCtlData* pTbCtlData = 0;
1535 ULONG itemCount;
1536
1537 pTbCtlData = (TbCtlData *)WinQueryWindowULong(hwnd, QWL_USER);
1538
1539 if(!pTbCtlData)
1540 {
1541 return 0;
1542 }
1543 switch(msg)
1544 {
1545
1546/* Internal messages */
1547
1548 case TKM_SEARCH_ID:
1549 {
1550 LONG lCount;
1551
1552 for(lCount = 0; lCount < pTbCtlData->lCount; lCount++)
1553 {
1554 if(WinQueryWindowUShort(pTbCtlData->hItems[lCount],
1555 QWS_ID) == (ULONG)mp1)
1556 return (MRESULT)pTbCtlData->hItems[lCount];
1557 }
1558 }
1559 return MRFROMSHORT(FALSE);
1560
1561 case TKM_QUERY_FLAGS:
1562 return MRFROMLONG(pTbCtlData->lState);
1563
1564/* Standard messages */
1565
1566 case WM_QUERYFRAMECTLCOUNT:
1567 {
1568 itemCount = (ULONG)(pTbCtlData->pOldProc(hwnd, msg, mp1, mp2));
1569 itemCount += pTbCtlData->lCount;
1570 }
1571 return MRFROMSHORT(itemCount);
1572
1573 case WM_FORMATFRAME:
1574 {
1575 PSWP pSWP = 0;
1576 USHORT usClient = 0;
1577 LONG lOffset = 0;
1578 LONG lCount;
1579 SWP swp;
1580
1581 itemCount = (ULONG)(pTbCtlData->pOldProc(hwnd, msg, mp1, mp2));
1582
1583 pSWP = (PSWP)PVOIDFROMMP(mp1);
1584
1585 while(pSWP[usClient].hwnd != WinWindowFromID(hwnd, FID_CLIENT))
1586 usClient++;
1587
1588 if(pTbCtlData->lState & TB_VERTICAL)
1589 lOffset = pSWP[usClient].cy - HAND_SIZE;
1590 else
1591 lOffset = HAND_SIZE + 1;
1592
1593
1594 for(lCount = 0; lCount < pTbCtlData->lCount; lCount++)
1595 {
1596 WinQueryWindowPos(pTbCtlData->hItems[lCount], &swp);
1597
1598
1599 if(pTbCtlData->lState & TB_VERTICAL)
1600 {
1601 pSWP[itemCount].x = pSWP[usClient].x;
1602 pSWP[itemCount].y = lOffset +
1603 pSWP[usClient].y - swp.cy;
1604 }
1605 else
1606 {
1607 pSWP[itemCount].x = pSWP[usClient].x + lOffset;
1608 pSWP[itemCount].y = pSWP[usClient].y;
1609 }
1610
1611 pSWP[itemCount].cx = swp.cx;
1612 pSWP[itemCount].cy = swp.cy;
1613 pSWP[itemCount].fl = SWP_SIZE | SWP_MOVE | SWP_SHOW;
1614 pSWP[itemCount].hwnd = pTbCtlData->hItems[lCount];
1615 pSWP[itemCount].hwndInsertBehind = HWND_TOP;
1616
1617 if(pTbCtlData->lState & TB_VERTICAL)
1618 lOffset -= swp.cy;
1619 else
1620 lOffset += swp.cx;
1621
1622 itemCount++;
1623 }
1624
1625 if(pTbCtlData->lState & TB_VERTICAL)
1626 {
1627 pSWP[usClient].y += pSWP[usClient].cy - HAND_SIZE;
1628 pSWP[usClient].cy = HAND_SIZE;
1629 }
1630 else
1631 pSWP[usClient].cx = HAND_SIZE;
1632 }
1633 return MRFROMSHORT(itemCount);
1634 }
1635 return pTbCtlData->pOldProc(hwnd, msg, mp1, mp2);
1636}
1637
1638/* Function: TbSeparatorProc
1639** Abstract: Window procedure for Toolbar Separator Window Class
1640*/
1641
1642MRESULT EXPENTRY TbSeparatorProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
1643{
1644 switch (msg)
1645 {
1646 case WM_PAINT:
1647 {
1648 HPS hpsPaint;
1649 RECTL rclPaint;
1650
1651 hpsPaint = WinBeginPaint(hwnd, 0, 0);
1652
1653 WinQueryWindowRect(hwnd, &rclPaint);
1654 WinFillRect(hpsPaint, &rclPaint, CLR_PALEGRAY);
1655
1656 WinEndPaint(hpsPaint);
1657 }
1658 return MRFROMSHORT(FALSE);
1659 }
1660 return WinDefWindowProc(hwnd, msg, mp1, mp2);
1661}
1662
1663/* Function: RecalcTbDimensions
1664** Abstract: Recalculate Toolbar window dimensions
1665*/
1666
1667void RecalcTbDimensions(HWND hwnd, POINTL * pSize)
1668{
1669 LONG lCount;
1670 POINTL ptlSize;
1671 POINTL ptlFSize;
1672 TbCtlData *pTbCtlData;
1673
1674 pTbCtlData = (TbCtlData *)WinQueryWindowULong(hwnd, QWL_USER);
1675
1676 ptlSize.x = (pTbCtlData->lState & TB_VERTICAL) ? 0 : HAND_SIZE;
1677 ptlSize.y = (pTbCtlData->lState & TB_VERTICAL) ? HAND_SIZE : 0;
1678
1679 for(lCount = 0; lCount < pTbCtlData->lCount; lCount++)
1680 {
1681 SWP swp;
1682
1683 WinQueryWindowPos(pTbCtlData->hItems[lCount], &swp);
1684
1685 if(pTbCtlData->lState & TB_VERTICAL)
1686 {
1687 if(swp.cx > ptlSize.x)
1688 ptlSize.x = swp.cx;
1689 ptlSize.y += swp.cy;
1690 }
1691 else
1692 {
1693 if(swp.cy > ptlSize.y)
1694 ptlSize.y = swp.cy;
1695 ptlSize.x += swp.cx;
1696 }
1697 }
1698
1699 WinSendMsg(hwnd, WM_QUERYBORDERSIZE, MPFROMP(&ptlFSize), 0);
1700 ptlSize.x += ptlFSize.x * 2;
1701 ptlSize.y += ptlFSize.y * 2;
1702
1703 if(pSize)
1704 *pSize = ptlSize;
1705 else
1706 WinSetWindowPos(hwnd, 0, 0, 0, ptlSize.x, ptlSize.y, SWP_SIZE);
1707
1708}
1709
1710/* Function: TrackRectangle
1711** Abstract: Tracks given rectangle.
1712**
1713** If rclBounds is NULL, then track rectangle on entire desktop.
1714** rclTrack is in window coorditates and will be mapped to
1715** desktop.
1716*/
1717
1718BOOL TrackRectangle(HWND hwndBase, RECTL* rclTrack, RECTL* rclBounds)
1719{
1720 TRACKINFO track;
1721 APIRET rc;
1722 POINTL ptlSize;
1723
1724 track.cxBorder = 1;
1725 track.cyBorder = 1;
1726 track.cxGrid = 1;
1727 track.cyGrid = 1;
1728 track.cxKeyboard = 1;
1729 track.cyKeyboard = 1;
1730
1731 if(!rclTrack)
1732 return FALSE;
1733
1734 if(rclBounds)
1735 {
1736 track.rclBoundary = *rclBounds;
1737 }
1738 else
1739 {
1740 track.rclBoundary.yTop =
1741 track.rclBoundary.xRight = 3000;
1742 track.rclBoundary.yBottom =
1743 track.rclBoundary.xLeft = -3000;
1744 }
1745
1746 track.rclTrack = *rclTrack;
1747
1748 WinMapWindowPoints(hwndBase,
1749 HWND_DESKTOP,
1750 (PPOINTL)&track.rclTrack,
1751 2);
1752
1753 track.ptlMinTrackSize.x = track.rclTrack.xRight
1754 - track.rclTrack.xLeft;
1755 track.ptlMinTrackSize.y = track.rclTrack.yTop
1756 - track.rclTrack.yBottom;
1757 track.ptlMaxTrackSize.x = track.rclTrack.xRight
1758 - track.rclTrack.xLeft;
1759 track.ptlMaxTrackSize.y = track.rclTrack.yTop
1760 - track.rclTrack.yBottom;
1761
1762 track.fs = TF_MOVE | TF_ALLINBOUNDARY | TF_GRID;
1763
1764 rc = WinTrackRect(HWND_DESKTOP, 0, &track);
1765
1766 if(rc)
1767 {
1768 if(!memcmp(&rclTrack, &track.rclTrack, sizeof(RECTL)))
1769 return -1;
1770
1771 *rclTrack = track.rclTrack;
1772 }
1773
1774 return rc;
1775}
1776
1777/* Function: TbClientProc
1778** Abstract: Window procedure for Toolbar Client Window Class
1779*/
1780
1781MRESULT EXPENTRY TbClientProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
1782{
1783 HWND hwndFrame = 0;
1784 TbCtlData* pTbCtlData;
1785 RECTL rclPaint;
1786
1787 hwndFrame = WinQueryWindow(hwnd, QW_PARENT);
1788 pTbCtlData = (TbCtlData *)WinQueryWindowULong(hwndFrame,
1789 QWL_USER);
1790 switch (msg)
1791 {
1792 case WM_ERASEBACKGROUND :
1793 {
1794 WinFillRect((HPS)mp1, (PRECTL)mp2, SYSCLR_BUTTONMIDDLE);
1795 }
1796 return MRFROMSHORT(FALSE);
1797
1798 case WM_PAINT:
1799 {
1800 HPS hpsPaint;
1801 POINTL ptlWork;
1802 int i;
1803
1804 hpsPaint = WinBeginPaint(hwnd, 0, 0);
1805 WinQueryWindowRect(hwnd, &rclPaint);
1806
1807 WinFillRect(hpsPaint, &rclPaint, CLR_PALEGRAY);
1808
1809 GpiSetColor(hpsPaint,CLR_WHITE);
1810
1811 ptlWork.x = rclPaint.xLeft + 2;
1812 ptlWork.y = rclPaint.yBottom + 2;
1813 GpiMove(hpsPaint, &ptlWork);
1814 ptlWork.y = rclPaint.yTop - 2;
1815 GpiLine(hpsPaint, &ptlWork);
1816 ptlWork.x = rclPaint.xRight - 2;
1817 GpiLine(hpsPaint, &ptlWork);
1818
1819 GpiSetColor(hpsPaint,CLR_BLACK);
1820
1821 ptlWork.y = rclPaint.yBottom + 2;
1822 GpiLine(hpsPaint, &ptlWork);
1823 ptlWork.x = rclPaint.xLeft + 2;
1824 GpiLine(hpsPaint, &ptlWork);
1825
1826 WinEndPaint(hpsPaint);
1827 }
1828 return MRFROMSHORT(FALSE);
1829
1830 case WM_MOUSEMOVE:
1831 {
1832 WinSetPointer(HWND_DESKTOP,
1833 WinQuerySysPointer(HWND_DESKTOP,
1834 SPTR_MOVE,
1835 FALSE));
1836 }
1837 return MRFROMSHORT(FALSE);
1838
1839 case WM_BUTTON2DBLCLK: /* Switch bubble help on/off */
1840 if(pTbCtlData->lState & TB_BUBBLE)
1841 {
1842 pTbCtlData->bBubble = 1 - pTbCtlData->bBubble;
1843 }
1844 break;
1845
1846 case WM_BUTTON1DBLCLK: /* Flip horisontal/vertical */
1847 {
1848 POINTL ptlPoint;
1849 SWP swp;
1850
1851 /* attached toolbar can't be flipped */
1852
1853 if(pTbCtlData->lState & TB_ATTACHED)
1854 return MRFROMSHORT(FALSE);
1855
1856 pTbCtlData->lState ^= TB_VERTICAL;
1857 WinShowWindow(hwndFrame, FALSE);
1858 RecalcTbDimensions(hwndFrame, 0);
1859
1860 /*
1861 ** Setup new position
1862 ** New positon should be aligned to mouse cursor
1863 */
1864
1865 WinQueryPointerPos(HWND_DESKTOP,&ptlPoint);
1866 WinQueryWindowPos(hwndFrame, &swp);
1867
1868 if(pTbCtlData->lState & TB_VERTICAL)
1869 WinSetWindowPos(hwndFrame, 0,
1870 ptlPoint.x - swp.cx/2,
1871 ptlPoint.y - swp.cy + HAND_SIZE/2,
1872 0,
1873 0,
1874 SWP_MOVE);
1875 else
1876 WinSetWindowPos(hwndFrame, 0,
1877 ptlPoint.x - HAND_SIZE/2,
1878 ptlPoint.y - swp.cy/2,
1879 0,
1880 0,
1881 SWP_MOVE);
1882
1883 WinShowWindow(hwndFrame, TRUE);
1884 }
1885 return MRFROMSHORT(FALSE);
1886
1887 case WM_BUTTON1DOWN:
1888 {
1889 RECTL rclOwner;
1890 RECTL rclFrame;
1891 LONG lState = 0;
1892 LONG lBorderX;
1893 LONG lBorderY;
1894 APIRET rc;
1895 POINTL ptlSize;
1896
1897 RecalcTbDimensions(hwndFrame, &ptlSize);
1898
1899 rclFrame.xLeft = 0;
1900 rclFrame.yBottom = 0;
1901 rclFrame.yTop = ptlSize.y;
1902 rclFrame.xRight = ptlSize.x;
1903
1904 if((pTbCtlData->lState & TB_ATTACHED) &&
1905 (pTbCtlData->lState & TB_VERTICAL))
1906 {
1907 int iShift;
1908
1909 WinQueryWindowRect(hwndFrame, &rclOwner);
1910
1911 iShift = rclOwner.yTop - rclOwner.yBottom - ptlSize.y;
1912
1913 rclFrame.yBottom += iShift;
1914 rclFrame.yTop += iShift;
1915 }
1916
1917 rc = TrackRectangle(hwndFrame, &rclFrame, 0);
1918
1919 if(rc != TRUE)
1920 break;
1921
1922 /*
1923 ** Check new position for the toolbar
1924 ** NOTE: order of checks is important
1925 */
1926
1927 WinQueryWindowRect(pTbCtlData->hwndParent, &rclOwner);
1928
1929 /* Map both points to the desktop */
1930
1931 WinMapWindowPoints(pTbCtlData->hwndParent,
1932 HWND_DESKTOP,
1933 (PPOINTL)&rclOwner,
1934 2);
1935
1936 /* Cut owner rect by titlebar and menu hight */
1937
1938 lBorderX = WinQuerySysValue(HWND_DESKTOP, SV_CXDLGFRAME);
1939 lBorderY = WinQuerySysValue(HWND_DESKTOP, SV_CYDLGFRAME);
1940
1941 if(WinWindowFromID(pTbCtlData->hwndParent, FID_MENU))
1942 rclOwner.yTop -= WinQuerySysValue(HWND_DESKTOP,
1943 SV_CYMENU);
1944
1945 if(WinWindowFromID(pTbCtlData->hwndParent, FID_TITLEBAR))
1946 rclOwner.yTop -= WinQuerySysValue(HWND_DESKTOP,
1947 SV_CYTITLEBAR);
1948
1949 lState = 0;
1950 if(rclFrame.xLeft >= rclOwner.xLeft - lBorderX * 2 &&
1951 rclFrame.xLeft <= rclOwner.xLeft + lBorderX * 2)
1952 lState = TB_ATTACHED_LT;
1953
1954 if(rclFrame.yTop >= rclOwner.yTop - lBorderY * 2 &&
1955 rclFrame.yTop <= rclOwner.yTop + lBorderY * 2 )
1956 lState = TB_ATTACHED_TP;
1957
1958 if(rclFrame.xRight >= rclOwner.xRight - lBorderX * 2 &&
1959 rclFrame.xRight <= rclOwner.xRight + lBorderX * 2)
1960 lState = TB_ATTACHED_RT;
1961
1962 if(rclFrame.yBottom >= rclOwner.yBottom - lBorderY * 2 &&
1963 rclFrame.yBottom <= rclOwner.yBottom + lBorderY * 2)
1964 lState = TB_ATTACHED_BT;
1965
1966 WinShowWindow(hwndFrame, FALSE);
1967
1968 if(!(pTbCtlData->lState & TB_ATTACHED) && !lState)
1969 {
1970 /* Toolbar is not attached and will not be attached
1971 this time. Just change its position.
1972 */
1973
1974 WinSetWindowPos(hwndFrame, 0,
1975 rclFrame.xLeft, rclFrame.yBottom,
1976 0, 0, SWP_MOVE);
1977 }
1978
1979 if(pTbCtlData->lState & TB_ATTACHED)
1980 {
1981 POINTL ptlPoint;
1982 SWP swp;
1983
1984 WinSetWindowBits(hwndFrame, QWL_STYLE, 0, FS_BORDER);
1985 WinSetWindowBits(hwndFrame, QWL_STYLE, FS_DLGBORDER,
1986 FS_DLGBORDER);
1987 WinSendMsg(hwndFrame,
1988 WM_UPDATEFRAME,
1989 MPFROMLONG(FCF_SIZEBORDER), 0);
1990
1991 pTbCtlData->lState &= ~TB_ATTACHED;
1992 WinSetParent(hwndFrame, HWND_DESKTOP, FALSE);
1993 RecalcTbDimensions(hwndFrame, 0);
1994
1995 WinQueryPointerPos(HWND_DESKTOP,&ptlPoint);
1996 WinQueryWindowPos(hwndFrame, &swp);
1997
1998 if(pTbCtlData->lState & TB_VERTICAL)
1999 WinSetWindowPos(hwndFrame, 0,
2000 ptlPoint.x - swp.cx/2,
2001 ptlPoint.y - swp.cy + HAND_SIZE/2,
2002 0,
2003 0,
2004 SWP_MOVE);
2005 else
2006 WinSetWindowPos(hwndFrame, 0,
2007 ptlPoint.x - HAND_SIZE/2,
2008 ptlPoint.y - swp.cy/2,
2009 0,
2010 0,
2011 SWP_MOVE);
2012 }
2013
2014 if(lState)
2015 {
2016 pTbCtlData->lState |= lState;
2017
2018 WinSetWindowBits(hwndFrame, QWL_STYLE, 0, FS_DLGBORDER);
2019
2020 WinSetWindowBits(hwndFrame, QWL_STYLE, FS_BORDER,
2021 FS_BORDER);
2022
2023 WinSendMsg(hwndFrame,
2024 WM_UPDATEFRAME,
2025 MPFROMLONG(FCF_SIZEBORDER), 0);
2026
2027 WinSetFocus(HWND_DESKTOP, pTbCtlData->hwndParent);
2028 WinSetParent(hwndFrame, pTbCtlData->hwndParent, FALSE);
2029
2030 if((lState & (TB_ATTACHED_LT | TB_ATTACHED_RT)) &&
2031 !(pTbCtlData->lState & TB_VERTICAL))
2032 {
2033 /*
2034 ** toolbar is horisontal, but we need to
2035 ** attach them to vertical side
2036 */
2037 pTbCtlData->lState ^= TB_VERTICAL;
2038 }
2039
2040 if((lState & (TB_ATTACHED_TP | TB_ATTACHED_BT)) &&
2041 (pTbCtlData->lState & TB_VERTICAL))
2042 {
2043 /*
2044 **toolbar is vertical, but we need to
2045 **attach them to horizontal side
2046 */
2047 pTbCtlData->lState ^= TB_VERTICAL;
2048 }
2049 RecalcTbDimensions(hwndFrame, 0);
2050 }
2051
2052 WinSendMsg(pTbCtlData->hwndParent, WM_UPDATEFRAME, 0, 0);
2053 WinShowWindow(hwndFrame, TRUE);
2054 WinSetWindowPos(hwndFrame, HWND_TOP, 0, 0, 0, 0, SWP_ZORDER);
2055 }
2056 return MRFROMSHORT(FALSE);
2057 }
2058 return WinDefWindowProc(hwnd, msg, mp1, mp2);
2059}
2060
2061/* Function: ToolkitInit
2062** Abstract: Registers classes needed for toolkit
2063*/
2064
2065void ToolkitInit(HAB aHab)
2066{
2067 hab = aHab;
2068 WinRegisterClass(hab,
2069 CELL_CLIENT,
2070 CellClientProc,
2071 CS_SIZEREDRAW,
2072 sizeof(ULONG));
2073
2074 WinRegisterClass(hab,
2075 TB_CLIENT,
2076 TbClientProc,
2077 CS_SIZEREDRAW,
2078 sizeof(ULONG));
2079
2080 WinRegisterClass(hab,
2081 TB_SEPCLASS,
2082 TbSeparatorProc,
2083 CS_SIZEREDRAW,
2084 sizeof(ULONG));
2085}
2086
2087/* Function: CreateToolbar
2088** Abstract: Creates toolbar for cell frame window
2089*/
2090
2091void CreateToolbar(HWND hwnd, TbDef* pTb)
2092{
2093 CellCtlData* pCtlData = 0;
2094 CellTb* pCellTb = 0;
2095 HWND hwndTb;
2096
2097 if(!pTb || !hwnd)
2098 return;
2099
2100 pCtlData = (CellCtlData *)WinQueryWindowULong(hwnd, QWL_USER);
2101
2102 if(!pCtlData)
2103 return;
2104
2105 hwndTb = CreateTb(pTb, hwnd, hwnd);
2106
2107 if(!hwndTb)
2108 return;
2109
2110 pCellTb = (CellTb*)malloc(sizeof(CellTb));
2111
2112 if(!pCellTb)
2113 return;
2114
2115 memset(pCellTb, 0, sizeof(CellTb));
2116
2117 pCellTb->hWnd = hwndTb;
2118 pCellTb->pNext = pCtlData->pCellTb;
2119 pCtlData->pCellTb = pCellTb;
2120
2121 WinSendMsg(hwnd, WM_UPDATEFRAME, 0, 0);
2122}
2123
2124/* Function: CellWindowFromID
2125** Abstract: Locate control window with given ID
2126*/
2127
2128HWND CellWindowFromID(HWND hwndCell, ULONG ulID)
2129{
2130 return (HWND)WinSendMsg(hwndCell, TKM_SEARCH_ID, MPFROMLONG(ulID), 0);
2131}
2132
2133/* Function: CellWindowFromID
2134** Abstract: Locate parent window for window with given ID
2135*/
2136
2137HWND CellParentWindowFromID(HWND hwndCell, ULONG ulID)
2138{
2139 return (HWND)WinSendMsg(hwndCell, TKM_SEARCH_PARENT, MPFROMLONG(ulID), 0);
2140}
2141
2142/* Function: GenResIDStr
2143** Abstract: Generate string '#nnnn' for a given ID for using with Button
2144** controls
2145*/
2146
2147void GenResIDStr(CHAR *buff, ULONG ulID)
2148{
2149 char *str;
2150 int slen = 0;
2151
2152 *buff++ = '#';
2153
2154 str = buff;
2155
2156 do
2157 {
2158 *str++ = (ulID % 10) + '0';
2159 ulID /= 10;
2160 slen++;
2161 }
2162 while(ulID);
2163
2164 *str-- = 0;
2165
2166 for(; str > buff; str--, buff++)
2167 {
2168 *buff ^= *str;
2169 *str ^= *buff;
2170 *buff ^= *str;
2171 }
2172}
2173
Note: See TracBrowser for help on using the repository browser.