2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
11 #include <afs/param.h>
19 #include <WINNT/dialog.h>
20 #include <WINNT/resize.h> // for GetRectInParent()
21 #include <WINNT/subclass.h>
22 #include <WINNT/ctl_spinner.h>
23 #include <WINNT/ctl_time.h>
24 #include <WINNT/TaLocale.h>
27 #define cchRESOURCE 256
32 * MISCELLANEOUS ______________________________________________________________
37 #define REALLOC(_a,_c,_r,_i) TimeReallocFunction ((LPVOID*)&_a,sizeof(*_a),&_c,_r,_i)
38 BOOL TimeReallocFunction (LPVOID *ppTarget, size_t cbElement, size_t *pcTarget, size_t cReq, size_t cInc)
43 if (cReq <= *pcTarget)
46 if ((cNew = cInc * ((cReq + cInc-1) / cInc)) <= 0)
49 if ((pNew = (LPVOID)Allocate (cbElement * cNew)) == NULL)
51 memset (pNew, 0x00, cbElement * cNew);
55 memcpy (pNew, *ppTarget, cbElement * (*pcTarget));
68 * TIME _______________________________________________________________________
87 SYSTEMTIME timeNow; // only hour and minute fields are relevant
95 static CRITICAL_SECTION csTime;
96 static TimeInfo *aTime = NULL;
97 static size_t cTime = 0;
99 #define cszTIMECLASS TEXT("Time")
101 BOOL CALLBACK TimeProc (HWND hTime, UINT msg, WPARAM wp, LPARAM lp);
102 BOOL CALLBACK TimeEditProc (HWND hEdit, UINT msg, WPARAM wp, LPARAM lp);
103 BOOL CALLBACK TimeDlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp);
105 void Time_SendCallback (TimeInfo *pti, WORD eln, LPARAM lp);
107 void Time_OnCreate (TimeInfo *pti);
108 void Time_OnDestroy (TimeInfo *pti);
109 void Time_OnButtonDown (TimeInfo *pti, UINT msg, WPARAM wp, LPARAM lp);
110 BOOL Time_OnGetTime (TimeInfo *pti, WPARAM wp, LPARAM lp);
111 BOOL Time_OnSetTime (TimeInfo *pti, WPARAM wp, LPARAM lp);
113 void Time_Edit_OnSetFocus (TimeInfo *pti, HWND hEdit);
114 void Time_Edit_OnUpdate (TimeInfo *pti, HWND hEdit);
115 void Time_Edit_SetText (TimeInfo *pti, HWND hEdit);
117 void Time_GetAMPMSize (HDC hdc, SIZE *pSize, LPTSTR pszAM, LPTSTR pszPM);
120 BOOL RegisterTimeClass (void)
122 static BOOL fRegistered = FALSE;
126 InitializeCriticalSection (&csTime);
129 memset (&wc, 0x00, sizeof(wc));
130 wc.style = CS_GLOBALCLASS;
131 wc.lpfnWndProc = (WNDPROC)TimeProc;
132 wc.hInstance = THIS_HINST;
133 wc.hCursor = LoadCursor (NULL, MAKEINTRESOURCE (IDC_ARROW));
134 wc.hbrBackground = CreateSolidBrush (GetSysColor (COLOR_BTNFACE));
135 wc.lpszClassName = cszTIMECLASS;
137 if (RegisterClass (&wc))
145 void Time_SendCallback (TimeInfo *pti, WORD eln, LPARAM lp)
147 if ((pti->fCanCallBack == TRUE) && !pti->fCallingBack)
149 pti->fCallingBack = TRUE;
151 SendMessage (GetParent (pti->hTime),
153 MAKELONG ((WORD)GetWindowLong (pti->hTime, GWL_ID), eln),
156 pti->fCallingBack = FALSE;
161 BOOL CALLBACK TimeProc (HWND hTime, UINT msg, WPARAM wp, LPARAM lp)
163 TimeInfo *pti = NULL;
165 EnterCriticalSection (&csTime);
167 if (msg == WM_CREATE)
169 for (size_t iTime = 0; iTime < cTime; ++iTime)
171 if (aTime[ iTime ].hTime == NULL)
176 if (!REALLOC (aTime, cTime, 1+iTime, 4))
180 memset (&aTime[ iTime ], 0x00, sizeof(TimeInfo));
181 aTime[ iTime ].hTime = hTime;
183 pti = &aTime[ iTime ];
187 for (size_t iTime = 0; !pti && iTime < cTime; ++iTime)
189 if (aTime[ iTime ].hTime == hTime)
190 pti = &aTime[ iTime ];
194 LeaveCriticalSection (&csTime);
205 Time_OnDestroy (pti);
210 Time_OnButtonDown (pti, msg, wp, lp);
214 PostMessage (GetParent(hTime), WM_NEXTDLGCTL, (WPARAM)pti->hHours, TRUE);
218 EnableWindow (pti->hHours, IsWindowEnabled (hTime));
219 EnableWindow (pti->hSep1, IsWindowEnabled (hTime));
220 EnableWindow (pti->hMinutes, IsWindowEnabled (hTime));
221 EnableWindow (pti->hSpinner, IsWindowEnabled (hTime));
225 EnableWindow (pti->hSep2, IsWindowEnabled (hTime));
226 EnableWindow (pti->hAMPM, IsWindowEnabled (hTime));
230 GetRectInParent (hTime, &rTime);
231 InvalidateRect (GetParent(hTime), &rTime, TRUE);
232 UpdateWindow (GetParent(hTime));
240 PostMessage (GetParent(pti->hSpinner), WM_VSCROLL, SB_LINEUP, (LPARAM)pti->hSpinner);
244 PostMessage (GetParent(pti->hSpinner), WM_VSCROLL, SB_LINEDOWN, (LPARAM)pti->hSpinner);
248 PostMessage (GetParent(pti->hSpinner), WM_VSCROLL, SB_PAGEUP, (LPARAM)pti->hSpinner);
252 PostMessage (GetParent(pti->hSpinner), WM_VSCROLL, SB_PAGEDOWN, (LPARAM)pti->hSpinner);
256 PostMessage (GetParent(pti->hSpinner), WM_VSCROLL, SB_TOP, (LPARAM)pti->hSpinner);
260 PostMessage (GetParent(pti->hSpinner), WM_VSCROLL, SB_BOTTOM, (LPARAM)pti->hSpinner);
266 return Time_OnGetTime (pti, wp, lp);
269 return Time_OnSetTime (pti, wp, lp);
273 return DefWindowProc (hTime, msg, wp, lp);
277 void Time_OnCreate (TimeInfo *pti)
279 Subclass_AddHook (GetParent(pti->hTime), TimeDlgProc);
281 TCHAR szTimeSep[ cchRESOURCE ];
282 if (!GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_STIME, szTimeSep, cchRESOURCE))
283 lstrcpy (szTimeSep, TEXT(":"));
285 TCHAR sz24Hour[ cchRESOURCE ];
286 if (!GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_ITIME, sz24Hour, cchRESOURCE))
287 pti->f24Hour = FALSE;
289 pti->f24Hour = (sz24Hour[0] == TEXT('1')) ? TRUE : FALSE;
291 TCHAR sz0Hour[ cchRESOURCE ];
292 if (!GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_ITLZERO, sz0Hour, cchRESOURCE))
293 pti->f0Hours = FALSE;
295 pti->f0Hours = (sz0Hour[0] == TEXT('1')) ? TRUE : FALSE;
298 GetClientRect (pti->hTime, &rTime);
300 POINT ptTime = {0,0};
301 ClientToScreen (pti->hTime, &ptTime);
302 ScreenToClient (GetParent (pti->hTime), &ptTime);
304 SIZE s88; // size of widest likely double-digit number
305 SIZE sTimeSep; // size of ":"
306 SIZE sAMPM; // size of "AM/PM" listbox
307 TCHAR szAM[ cchRESOURCE ];
308 TCHAR szPM[ cchRESOURCE ];
310 HDC hdc = GetDC (GetParent (pti->hTime));
311 GetTextExtentPoint (hdc, TEXT("88"), lstrlen(TEXT("88")), &s88);
312 GetTextExtentPoint (hdc, szTimeSep, lstrlen(szTimeSep), &sTimeSep);
314 Time_GetAMPMSize (hdc, &sAMPM, szAM, szPM);
315 ReleaseDC (GetParent (pti->hTime), hdc);
317 LONG cxNumbers = cxRECT(rTime) - GetSystemMetrics (SM_CXVSCROLL) - (sTimeSep.cx);
319 cxNumbers -= sTimeSep.cx + sAMPM.cx;
320 LONG cxMinutes = max( cxNumbers/2, s88.cx );
321 LONG cxHours = cxNumbers - cxMinutes;
323 cxMinutes = min (cxMinutes, (LONG)( 1.2 * s88.cx ));
324 cxHours = min (cxHours, (LONG)( 1.2 * s88.cx )); // don't be TOO wide.
326 LONG cy = cyRECT(rTime);
329 pti->idHours = 100+NextControlID (GetParent (pti->hTime));
330 pti->hHours = CreateWindow (
333 WS_CHILD | WS_TABSTOP | ES_MULTILINE | ES_RIGHT | ES_NUMBER,
334 ptTime.x, yy, cxHours, cy,
335 GetParent(pti->hTime),
340 pti->hSep1 = CreateWindow (
343 WS_CHILD | SS_CENTER,
344 ptTime.x + cxHours, yy, sTimeSep.cx, cy,
345 GetParent(pti->hTime),
350 pti->idMinutes = 100+NextControlID (GetParent (pti->hTime));
351 pti->hMinutes = CreateWindow (
354 WS_CHILD | WS_TABSTOP | ES_MULTILINE | ES_RIGHT | ES_NUMBER,
355 ptTime.x + cxHours + sTimeSep.cx, yy, cxMinutes, cy,
356 GetParent(pti->hTime),
357 (HMENU)pti->idMinutes,
363 pti->hSep2 = CreateWindow (
366 WS_CHILD | SS_CENTER,
367 ptTime.x + cxHours + cxMinutes + sTimeSep.cx, yy, sTimeSep.cx, cy,
368 GetParent(pti->hTime),
373 pti->idAMPM = 100+NextControlID (GetParent (pti->hTime));
374 pti->hAMPM = CreateWindow (
377 WS_CHILD | WS_TABSTOP | LBS_NOINTEGRALHEIGHT | LBS_HASSTRINGS | LBS_OWNERDRAWFIXED | LBS_NOTIFY,
378 ptTime.x + cxHours + cxMinutes + 2 * sTimeSep.cx, yy, sAMPM.cx, cy,
379 GetParent(pti->hTime),
385 Subclass_AddHook (pti->hHours, TimeEditProc);
386 Subclass_AddHook (pti->hMinutes, TimeEditProc);
389 Subclass_AddHook (pti->hAMPM, TimeEditProc);
391 HFONT hf = (HFONT)SendMessage (GetParent (pti->hTime), WM_GETFONT, 0, 0);
392 SendMessage (pti->hHours, WM_SETFONT, (WPARAM)hf, MAKELPARAM(TRUE,0));
393 SendMessage (pti->hSep1, WM_SETFONT, (WPARAM)hf, MAKELPARAM(TRUE,0));
394 SendMessage (pti->hMinutes, WM_SETFONT, (WPARAM)hf, MAKELPARAM(TRUE,0));
398 SendMessage (pti->hSep2, WM_SETFONT, (WPARAM)hf, MAKELPARAM(TRUE,0));
399 SendMessage (pti->hAMPM, WM_SETFONT, (WPARAM)hf, MAKELPARAM(TRUE,0));
402 EnableWindow (pti->hHours, IsWindowEnabled (pti->hTime));
403 EnableWindow (pti->hSep1, IsWindowEnabled (pti->hTime));
404 EnableWindow (pti->hMinutes, IsWindowEnabled (pti->hTime));
408 EnableWindow (pti->hSep2, IsWindowEnabled (pti->hTime));
409 EnableWindow (pti->hAMPM, IsWindowEnabled (pti->hTime));
411 LB_StartChange (pti->hAMPM, TRUE);
412 LB_AddItem (pti->hAMPM, szAM, 0);
413 LB_AddItem (pti->hAMPM, szPM, 1);
414 LB_EndChange (pti->hAMPM);
415 LB_SetSelected (pti->hAMPM, 1);
418 ShowWindow (pti->hHours, TRUE);
419 ShowWindow (pti->hSep1, TRUE);
420 ShowWindow (pti->hMinutes, TRUE);
424 ShowWindow (pti->hSep2, TRUE);
425 ShowWindow (pti->hAMPM, TRUE);
429 GetWindowRect (pti->hTime, &rWindow);
430 rWindow.right += (cxHours + cxMinutes + sTimeSep.cx) - cxRECT(rTime);
432 rWindow.right += sTimeSep.cx + sAMPM.cx;
434 SetWindowPos (pti->hTime, NULL, 0, 0, cxRECT(rWindow), cyRECT(rWindow),
435 SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
438 GetRectInParent (pti->hTime, &rSpinner);
439 rSpinner.left = rSpinner.right;
440 rSpinner.right = rSpinner.left + GetSystemMetrics (SM_CXVSCROLL);
441 rSpinner.bottom -= 2; // just like Win95 does
442 CreateSpinner (pti->hHours, 10, FALSE, 0, pti->timeNow.wHour, 24, &rSpinner);
443 pti->hSpinner = SP_GetSpinner (pti->hHours);
444 pti->hSpinnerBuddy = pti->hHours;
446 Time_Edit_SetText (pti, pti->hHours);
447 Time_Edit_SetText (pti, pti->hMinutes);
448 Time_Edit_OnSetFocus (pti, pti->hHours);
449 pti->fCanCallBack = TRUE;
453 void Time_OnDestroy (TimeInfo *pti)
455 Subclass_RemoveHook (GetParent(pti->hTime), TimeDlgProc);
460 void Time_OnButtonDown (TimeInfo *pti, UINT msg, WPARAM wp, LPARAM lp)
462 DWORD dw = GetMessagePos();
465 pt.y = HIWORD(dw); // in screen coordinates
470 GetWindowRect (pti->hHours, &rTarget);
471 if (PtInRect (&rTarget, pt))
472 hTarget = pti->hHours;
474 GetWindowRect (pti->hMinutes, &rTarget);
475 if (PtInRect (&rTarget, pt))
476 hTarget = pti->hMinutes;
480 GetWindowRect (pti->hAMPM, &rTarget);
481 if (PtInRect (&rTarget, pt))
482 hTarget = pti->hAMPM;
487 PostMessage (hTarget, msg, wp, lp);
492 BOOL Time_OnGetTime (TimeInfo *pti, WPARAM wp, LPARAM lp)
494 SYSTEMTIME *ptime = (SYSTEMTIME*)lp;
495 ptime->wHour = pti->timeNow.wHour;
496 ptime->wMinute = pti->timeNow.wMinute;
497 ptime->wSecond = pti->timeNow.wSecond;
498 ptime->wMilliseconds = pti->timeNow.wMilliseconds;
503 BOOL Time_OnSetTime (TimeInfo *pti, WPARAM wp, LPARAM lp)
505 SYSTEMTIME *ptime = (SYSTEMTIME*)lp;
506 pti->timeNow = *ptime;
508 Time_Edit_SetText (pti, pti->hHours);
509 Time_Edit_SetText (pti, pti->hMinutes);
515 BOOL CALLBACK TimeDlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
517 PVOID oldProc = Subclass_FindNextHook (hDlg, TimeDlgProc);
522 case WM_CTLCOLOREDIT:
523 case WM_CTLCOLORSTATIC:
524 case WM_CTLCOLORLISTBOX:
525 for (iTime = 0; iTime < cTime; ++iTime)
527 if (aTime[ iTime ].hTime == NULL)
529 if ( (aTime[ iTime ].hHours == (HWND)lp) ||
530 (aTime[ iTime ].hSep1 == (HWND)lp) ||
531 (aTime[ iTime ].hMinutes == (HWND)lp) ||
532 ((!aTime[ iTime ].f24Hour) && (aTime[ iTime ].hSep2 == (HWND)lp)) ||
533 ((!aTime[ iTime ].f24Hour) && (aTime[ iTime ].hAMPM == (HWND)lp)) )
536 if (IsWindowEnabled (aTime[ iTime ].hTime))
537 clr = GetSysColor (COLOR_WINDOW);
539 clr = GetSysColor (COLOR_BTNFACE);
540 SetBkColor ((HDC)wp, clr);
541 return (BOOL)CreateSolidBrush (clr);
547 LPMEASUREITEMSTRUCT lpmis;
548 lpmis = (LPMEASUREITEMSTRUCT)lp;
552 Time_GetAMPMSize (hdc, &sAMPM, NULL, NULL);
553 ReleaseDC (hDlg, hdc);
554 lpmis->itemHeight = sAMPM.cy;
558 LPDRAWITEMSTRUCT lpdis;
559 lpdis = (LPDRAWITEMSTRUCT)lp;
563 if (!IsWindowEnabled (lpdis->hwndItem))
565 clrBack = GetSysColor (COLOR_BTNFACE);
566 clrFore = GetSysColor (COLOR_GRAYTEXT);
568 else if ((lpdis->itemState & ODS_SELECTED) && (GetFocus() == lpdis->hwndItem))
570 clrBack = GetSysColor (COLOR_HIGHLIGHT);
571 clrFore = GetSysColor (COLOR_HIGHLIGHTTEXT);
575 clrBack = GetSysColor (COLOR_WINDOW);
576 clrFore = GetSysColor (COLOR_BTNTEXT);
579 TCHAR szText[ cchRESOURCE ];
580 SendMessage (lpdis->hwndItem, LB_GETTEXT, lpdis->itemID, (LPARAM)szText);
582 SetTextColor (lpdis->hDC, clrFore);
583 SetBkColor (lpdis->hDC, clrBack);
584 SetBkMode (lpdis->hDC, OPAQUE);
585 TextOut (lpdis->hDC, 0, lpdis->rcItem.top, szText, lstrlen(szText));
589 for (iTime = 0; iTime < cTime; ++iTime)
591 if (aTime[ iTime ].hTime == NULL)
593 if ( (aTime[ iTime ].idHours == LOWORD(wp)) ||
594 (aTime[ iTime ].idMinutes == LOWORD(wp)) ||
595 ((!aTime[ iTime ].f24Hour) && (aTime[ iTime ].idAMPM == LOWORD(wp))) )
597 if (HIWORD(wp) == SPN_UPDATE)
599 Time_Edit_OnUpdate (&aTime[ iTime ], GetDlgItem(hDlg,LOWORD(wp)));
608 return CallWindowProc ((WNDPROC)oldProc, hDlg, msg, wp, lp);
610 return DefWindowProc (hDlg, msg, wp, lp);
614 BOOL CALLBACK TimeEditProc (HWND hEdit, UINT msg, WPARAM wp, LPARAM lp)
616 TimeInfo *pti = NULL;
618 EnterCriticalSection (&csTime);
620 for (size_t iTime = 0; !pti && iTime < cTime; ++iTime)
622 if ( (aTime[ iTime ].hHours == hEdit) ||
623 (aTime[ iTime ].hMinutes == hEdit) ||
624 ((!aTime[ iTime ].f24Hour) && (aTime[ iTime ].hAMPM == hEdit)) )
626 pti = &aTime[ iTime ];
630 LeaveCriticalSection (&csTime);
637 Time_Edit_OnSetFocus (pti, hEdit);
642 PVOID oldProc = Subclass_FindNextHook (hEdit, TimeEditProc);
644 return CallWindowProc ((WNDPROC)oldProc, hEdit, msg, wp, lp);
646 return DefWindowProc (hEdit, msg, wp, lp);
650 void Time_Edit_OnSetFocus (TimeInfo *pti, HWND hEdit)
656 pti->fCanCallBack --;
658 if (hEdit == pti->hHours)
660 dwMin = (pti->f24Hour) ? 0 : 1;
661 dwNow = (pti->f24Hour) ? pti->timeNow.wHour : (pti->timeNow.wHour % 12);
662 dwMax = (pti->f24Hour) ? 24 : 12;
664 if (!pti->f24Hour && !dwNow)
667 else if (hEdit == pti->hMinutes)
670 dwNow = pti->timeNow.wMinute;
673 else // (hEdit == pti->hAMPM)
676 dwNow = (pti->timeNow.wHour >= 12) ? 1 : 0;
680 if (pti->hSpinnerBuddy != hEdit)
682 SP_SetBuddy (pti->hSpinnerBuddy, hEdit, FALSE);
683 pti->hSpinnerBuddy = hEdit;
686 SP_SetRange (hEdit, dwMin, dwMax);
687 SP_SetPos (hEdit, dwNow);
689 if ((hEdit == pti->hHours) && (!pti->f0Hours))
690 SP_SetFormat (hEdit, TEXT("%lu"));
691 else if ((hEdit == pti->hHours) || (hEdit == pti->hMinutes))
692 SP_SetFormat (hEdit, TEXT("%02lu"));
694 if ((hEdit == pti->hHours) || (hEdit == pti->hMinutes))
695 SendMessage (hEdit, EM_SETSEL, (WPARAM)0, (LPARAM)-1); // select all
697 pti->fCanCallBack ++;
701 void Time_Edit_OnUpdate (TimeInfo *pti, HWND hEdit)
703 TCHAR szText[ cchRESOURCE ];
705 if ((hEdit == pti->hHours) || (hEdit == pti->hAMPM))
707 GetWindowText (pti->hHours, szText, 256);
708 pti->timeNow.wHour = (WORD)atol (szText);
712 if ((pti->timeNow.wHour < 12) && (LB_GetSelected (pti->hAMPM) == 1))
713 pti->timeNow.wHour += 12;
714 else if ((pti->timeNow.wHour >= 12) && (LB_GetSelected (pti->hAMPM) == 0))
715 pti->timeNow.wHour -= 12;
719 if (hEdit == pti->hMinutes)
721 GetWindowText (pti->hMinutes, szText, 256);
722 pti->timeNow.wMinute = (WORD)atol (szText);
725 if ((pti->timeNow.wHour == 24) && (pti->timeNow.wMinute != 0))
727 pti->timeNow.wMinute = 0;
728 Time_Edit_SetText (pti, pti->hMinutes);
731 SYSTEMTIME st = pti->timeNow;
732 Time_SendCallback (pti, TN_UPDATE, (LPARAM)&st);
736 void Time_Edit_SetText (TimeInfo *pti, HWND hEdit)
740 if (hEdit == pti->hHours)
742 BOOL fPM = (pti->timeNow.wHour >= 12) ? TRUE : FALSE;
745 dwNow = pti->timeNow.wHour;
746 else if ((dwNow = pti->timeNow.wHour % 12) == 0)
749 if (pti->hSpinnerBuddy == hEdit)
751 SP_SetPos (hEdit, dwNow);
755 TCHAR szText[ cchRESOURCE ];
758 wsprintf (szText, TEXT("%lu"), dwNow);
760 wsprintf (szText, TEXT("%02lu"), dwNow);
762 SetWindowText (hEdit, szText);
767 LB_SetSelected (pti->hAMPM, (int)fPM);
770 else if (hEdit == pti->hMinutes)
772 if (pti->hSpinnerBuddy == hEdit)
774 SP_SetPos (hEdit, pti->timeNow.wMinute);
778 TCHAR szText[ cchRESOURCE ];
779 wsprintf (szText, TEXT("%02lu"), pti->timeNow.wMinute);
780 SetWindowText (hEdit, szText);
786 void Time_GetAMPMSize (HDC hdc, SIZE *pSize, LPTSTR pszAM, LPTSTR pszPM)
788 TCHAR szAM[ cchRESOURCE ];
789 TCHAR szPM[ cchRESOURCE ];
795 if (!GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_S1159, pszAM, cchRESOURCE))
796 lstrcpy (pszAM, TEXT("AM"));
798 if (!GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_S2359, pszPM, cchRESOURCE))
799 lstrcpy (pszPM, TEXT("PM"));
801 SIZE sAM; // size of "AM"
802 GetTextExtentPoint (hdc, pszAM, lstrlen(pszAM), &sAM);
804 SIZE sPM; // size of "PM"
805 GetTextExtentPoint (hdc, pszPM, lstrlen(pszPM), &sPM);
806 pSize->cx = max( sAM.cx, sPM.cx );
807 pSize->cy = max( sAM.cy, sPM.cy );