sizetip.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. #include <windows.h>
  2. #include <winreg.h>
  3. #include <tchar.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include "putty.h"
  7. ATOM tip_class = 0;
  8. HFONT tip_font;
  9. COLORREF tip_bg;
  10. COLORREF tip_text;
  11. LRESULT CALLBACK SizeTipWndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
  12. {
  13. switch (nMsg) {
  14. case WM_ERASEBKGND:
  15. return TRUE;
  16. case WM_PAINT:
  17. {
  18. HBRUSH hbr;
  19. HGDIOBJ holdbr;
  20. RECT cr;
  21. int wtlen;
  22. LPTSTR wt;
  23. HDC hdc;
  24. PAINTSTRUCT ps;
  25. hdc = BeginPaint(hWnd, &ps);
  26. SelectObject(hdc, tip_font);
  27. SelectObject(hdc, GetStockObject(BLACK_PEN));
  28. hbr = CreateSolidBrush(tip_bg);
  29. holdbr = SelectObject(hdc, hbr);
  30. GetClientRect(hWnd, &cr);
  31. Rectangle(hdc, cr.left, cr.top, cr.right, cr.bottom);
  32. wtlen = GetWindowTextLength(hWnd);
  33. wt = (LPTSTR)malloc((wtlen+1)*sizeof(TCHAR));
  34. GetWindowText(hWnd, wt, wtlen+1);
  35. SetTextColor(hdc, tip_text);
  36. SetBkColor(hdc, tip_bg);
  37. TextOut(hdc, cr.left+3, cr.top+3, wt, wtlen);
  38. free(wt);
  39. SelectObject(hdc, holdbr);
  40. DeleteObject(hbr);
  41. EndPaint(hWnd, &ps);
  42. }
  43. return 0;
  44. case WM_NCHITTEST:
  45. return HTTRANSPARENT;
  46. case WM_DESTROY:
  47. DeleteObject(tip_font);
  48. tip_font = NULL;
  49. break;
  50. case WM_SETTEXT:
  51. {
  52. LPCTSTR str = (LPCTSTR)lParam;
  53. SIZE sz;
  54. HDC hdc = CreateCompatibleDC(NULL);
  55. SelectObject(hdc, tip_font);
  56. GetTextExtentPoint32(hdc, str, _tcslen(str), &sz);
  57. SetWindowPos(hWnd, NULL, 0, 0, sz.cx+6, sz.cy+6, SWP_NOZORDER|SWP_NOMOVE|SWP_NOACTIVATE);
  58. InvalidateRect(hWnd, NULL, FALSE);
  59. DeleteDC(hdc);
  60. }
  61. break;
  62. }
  63. return DefWindowProc(hWnd, nMsg, wParam, lParam);
  64. }
  65. HWND tip_wnd = NULL;
  66. int tip_enabled = 0;
  67. void UpdateSizeTip(HWND src, int cx, int cy)
  68. {
  69. TCHAR str[32];
  70. if (!tip_enabled) return;
  71. if (!tip_wnd) {
  72. NONCLIENTMETRICS nci;
  73. /* First make sure the window class is registered */
  74. if (!tip_class) {
  75. WNDCLASS wc;
  76. wc.style = CS_HREDRAW|CS_VREDRAW;
  77. wc.lpfnWndProc = SizeTipWndProc;
  78. wc.cbClsExtra = 0;
  79. wc.cbWndExtra = 0;
  80. wc.hInstance = putty_inst;
  81. wc.hIcon = NULL;
  82. wc.hCursor = NULL;
  83. wc.hbrBackground = NULL;
  84. wc.lpszMenuName = NULL;
  85. wc.lpszClassName = "SizeTipClass";
  86. tip_class = RegisterClass(&wc);
  87. }
  88. #if 0
  89. /* Default values based on Windows Standard color scheme */
  90. tip_font = GetStockObject(SYSTEM_FONT);
  91. tip_bg = RGB(255, 255, 225);
  92. tip_text = RGB(0, 0, 0);
  93. #endif
  94. /* Prepare other GDI objects and drawing info */
  95. tip_bg = GetSysColor(COLOR_INFOBK);
  96. tip_text = GetSysColor(COLOR_INFOTEXT);
  97. memset(&nci, 0, sizeof(NONCLIENTMETRICS));
  98. nci.cbSize = sizeof(NONCLIENTMETRICS);
  99. SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &nci, 0);
  100. tip_font = CreateFontIndirect(&nci.lfStatusFont);
  101. }
  102. /* Generate the tip text */
  103. sprintf(str, "%dx%d", cx, cy);
  104. if (!tip_wnd) {
  105. HDC hdc;
  106. SIZE sz;
  107. RECT wr;
  108. int ix, iy;
  109. /* calculate the tip's size */
  110. hdc = CreateCompatibleDC(NULL);
  111. GetTextExtentPoint32(hdc, str, _tcslen(str), &sz);
  112. DeleteDC(hdc);
  113. GetWindowRect(src, &wr);
  114. ix = wr.left;
  115. if (ix<16) ix = 16;
  116. iy = wr.top - sz.cy;
  117. if (iy<16) iy = 16;
  118. /* Create the tip window */
  119. tip_wnd = CreateWindowEx(WS_EX_TOOLWINDOW|WS_EX_TOPMOST, MAKEINTRESOURCE(tip_class), str, WS_POPUP,
  120. ix, iy, sz.cx, sz.cy,
  121. NULL, NULL, putty_inst, NULL);
  122. ShowWindow(tip_wnd, SW_SHOWNOACTIVATE);
  123. } else {
  124. /* Tip already exists, just set the text */
  125. SetWindowText(tip_wnd, str);
  126. }
  127. }
  128. void EnableSizeTip(int bEnable)
  129. {
  130. if (tip_wnd && !bEnable) {
  131. DestroyWindow(tip_wnd);
  132. tip_wnd = NULL;
  133. }
  134. tip_enabled = bEnable;
  135. }