/[winpt]/trunk/Src/wptBalloonPop.cpp
ViewVC logotype

Annotation of /trunk/Src/wptBalloonPop.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 441 - (hide annotations)
Sat Apr 14 14:11:03 2012 UTC (12 years, 10 months ago) by twoaday
File size: 7163 byte(s)
2012-04-14  Timo Schulz  <twoaday@gmx.net>

        * wptBalloonPop.cpp (window_proc): Removed unused variable.
        * wptCardDlg.cpp (do_askpin): Corrected generation of PIN
        info text. Thanks to Grzesiek.
			

1 twoaday 340 /* wptBalloonPop.cpp - Balloon Popup-Box
2     * Copyright (C) 2009 Timo Schulz
3     *
4     * This file is part of WinPT.
5     *
6     * WinPT is free software; you can redistribute it and/or
7     * modify it under the terms of the GNU General Public License
8     * as published by the Free Software Foundation; either version 2
9     * of the License, or (at your option) any later version.
10     *
11     * WinPT is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14     * General Public License for more details.
15     */
16    
17    
18     /* The idea is to use a balloon style 'error message' which
19     points to the control the error happened at. For instance
20     if no valid E-Mail address was entered, the balloon message
21     contains an error description with an arrow to the edit field
22     the address was supposed to be entered in. */
23    
24     #include <windows.h>
25     #include <stdio.h>
26     #include <time.h>
27    
28     #include "wptTypes.h"
29    
30     #define BT_WINDOWNAME "WinPT_BalloonPop"
31     #define BT_TIMER_IDENTIFIER 23
32     #define BT_IOFFSET 8
33    
34    
35     extern HINSTANCE glob_hinst;
36    
37     struct balloon_ctx_s {
38     LPCTSTR text;
39     LPCTSTR icon_name;
40     POINT pos;
41     HWND hwnd;
42     };
43     static struct balloon_ctx_s glob_msg;
44     static BOOL window_class_registered = FALSE;
45    
46    
47     static void
48     display_balloon_text (HWND hwnd, HDC hdc, const char *text)
49     {
50     RECT rc;
51     memset (&rc, 0, sizeof (rc));
52     GetClientRect(hwnd, &rc);
53    
54     POINT pts[3];
55     pts[0].x = rc.left + BT_IOFFSET;
56     pts[0].y = rc.top;
57     pts[1].x = pts[0].x;
58     pts[1].y = pts[0].y + BT_IOFFSET;
59     pts[2].x = pts[1].x + BT_IOFFSET;
60     pts[2].y = pts[1].y;
61    
62     // we merge three regions here:
63     // 1) basis
64     // 2) rounded box
65     // 3) arrow
66     HRGN hrgn = CreateRectRgn(0, 0, 0, 0);
67     HRGN hrgn1 = CreateRoundRectRgn(rc.left,
68     rc.top + BT_IOFFSET,
69     rc.right,
70     rc.bottom,
71     15, 15);
72     HRGN hrgn2 = CreatePolygonRgn(&pts[0], 3, ALTERNATE);
73     CombineRgn(hrgn, hrgn1, hrgn2, RGN_OR);
74    
75     // fill the region and draw a frame around it
76     FillRgn (hdc, hrgn, GetSysColorBrush(COLOR_INFOBK));
77     FrameRgn (hdc, hrgn, (HBRUSH)GetStockObject (DKGRAY_BRUSH), 1, 1);
78    
79     rc.top = rc.top + BT_IOFFSET*2;
80     rc.bottom = rc.bottom - BT_IOFFSET;
81     rc.left = rc.left + BT_IOFFSET;
82     rc.right = rc.right - BT_IOFFSET;
83    
84     // FIXME: calculate best position
85     HICON hicon = LoadIcon (NULL, glob_msg.icon_name);
86     if (hicon != NULL) {
87     DrawIconEx (hdc, 5, 20, hicon, 28, 28, 0, NULL, DI_NORMAL);
88     DestroyIcon (hicon);
89     }
90    
91     SetTextColor (hdc, GetSysColor (COLOR_INFOTEXT));
92     DrawText (hdc, text, strlen (text), &rc, DT_VCENTER + DT_NOCLIP);
93     }
94    
95    
96     // window procedure for the balloon tip.
97     static LRESULT CALLBACK
98     window_proc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
99     {
100     switch (msg) {
101     case WM_PAINT:
102     RECT rc;
103     GetWindowRect (hwnd, &rc);
104    
105     POINT curpos;
106     curpos.x = glob_msg.pos.x;
107     curpos.y = glob_msg.pos.y;
108    
109     rc.right = curpos.x - BT_IOFFSET + 6 + rc.right - rc.left;
110     rc.bottom = curpos.y + 20 + rc.bottom - rc.top;
111     rc.left = curpos.x - BT_IOFFSET + 6;
112     rc.top = curpos.y + 20;
113     MoveWindow (hwnd, rc.left, rc.top, rc.right - rc.left,
114     rc.bottom - rc.top, FALSE);
115    
116     PAINTSTRUCT ps;
117 twoaday 441 BeginPaint (hwnd, &ps);
118 twoaday 340
119     LOGFONT lf;
120     memset (&lf, 0, sizeof (lf));
121     lf.lfHeight = 13;
122     lf.lfWeight = FW_NORMAL;
123     lf.lfQuality = ANTIALIASED_QUALITY;
124     strcpy (lf.lfFaceName, "MS Sans Serif");
125    
126     HFONT hfont;
127     hfont = CreateFontIndirect(&lf);
128     HFONT hfont_old;
129     hfont_old = (HFONT)SelectObject(ps.hdc, hfont);
130    
131     DrawText (ps.hdc, glob_msg.text, strlen (glob_msg.text),
132     &rc, DT_VCENTER+DT_NOCLIP+DT_CALCRECT);
133     rc.right = rc.right + 2*BT_IOFFSET;
134     rc.bottom = rc.bottom + 3*BT_IOFFSET;
135    
136     ShowWindow (hwnd, SW_SHOWNA);
137     MoveWindow(hwnd, rc.left, rc.top, rc.right - rc.left,
138     rc.bottom - rc.top, TRUE);
139     SetBkMode(ps.hdc, TRANSPARENT);
140     display_balloon_text (hwnd, ps.hdc, glob_msg.text);
141    
142     // restore old font object
143     SelectObject(ps.hdc, hfont_old);
144     DeleteObject (hfont);
145     EndPaint (hwnd, &ps);
146     break;
147    
148     case WM_LBUTTONUP:
149     ShowWindow (hwnd, SW_HIDE);
150     break;
151    
152     default:
153     return DefWindowProc (hwnd, msg, wparam, lparam);
154     }
155    
156     return FALSE;
157     }
158    
159    
160     /* Callback procedure to hide the baloon window after the
161     time has been expired */
162     static VOID CALLBACK
163     popup_timer_proc (HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
164     {
165     ShowWindow (hwnd, SW_HIDE);
166     }
167    
168    
169     /* Register our new window class */
170     static void
171     register_window_class (HINSTANCE hinst)
172     {
173     WNDCLASS wclass;
174     memset (&wclass, 0, sizeof (wclass));
175     wclass.style = CS_HREDRAW | CS_VREDRAW;
176     wclass.lpfnWndProc = window_proc;
177     wclass.hInstance = hinst;
178     wclass.lpszClassName = BT_WINDOWNAME;
179    
180     if (!RegisterClass (&wclass))
181     abort ();
182     }
183    
184    
185     static LPCTSTR
186     format_text (LPCTSTR string)
187     {
188     const int off = 12;
189     static char buf[2048];
190     int n = strlen (string), pos=0, i;
191    
192     memset (buf, 0, DIM (buf));
193     // FIXME: rewrite the function
194     if (n > 1600)
195     abort ();
196    
197     buf[pos++] = '\n';
198     for (i=0; i < off; i++)
199     buf[pos++] = ' ';
200     for (i=0; i < n; i++) {
201     buf[pos++] = string[i];
202     if (string[i] == '\n') {
203     for (int j=0; j < off; j++)
204     buf[pos++] = ' ';
205     }
206     }
207     buf[pos++] = '\n';
208     return buf;
209     }
210    
211    
212     /* Display a baloon message box at the given X- Y-coordinates */
213     HWND
214     show_balloon_msg_pos (HWND hparwnd, int millis, int x, int y,
215     LPCTSTR string, LPCTSTR icon_name)
216     {
217     if (!window_class_registered) {
218     register_window_class (glob_hinst);
219     window_class_registered = TRUE;
220     }
221    
222     // if no icon is requsted, print the text as it is.
223     if (!icon_name)
224     glob_msg.text = string;
225     else
226     glob_msg.text = format_text (string);
227     glob_msg.icon_name = icon_name;
228    
229     if (x > 0 && y > 0) { // use specific coordinates
230     glob_msg.pos.x = x;
231     glob_msg.pos.y = y;
232     }
233     else { // point to the lower left region of the control
234     RECT rect;
235     GetWindowRect (hparwnd, &rect);
236     glob_msg.pos.x = rect.left;
237     glob_msg.pos.y = rect.bottom - 20;
238     }
239    
240     // we use a persistent window for the balloon messages
241     // instead of destroy/create we hide the window whenever it
242     // is unused.
243     if (!glob_msg.hwnd) {
244     glob_msg.hwnd = CreateWindowEx (WS_EX_TOOLWINDOW | WS_EX_TOPMOST,
245     BT_WINDOWNAME, BT_WINDOWNAME,
246     WS_POPUP, 1, 1, 1, 1,
247     NULL, NULL, glob_hinst, NULL);
248     if (!glob_msg.hwnd)
249     BUG (0);
250     }
251    
252     // ensure 'parent' never loses focus.
253     HWND hwnd = glob_msg.hwnd;
254     ShowWindow (hwnd, SW_SHOW);
255     UpdateWindow (hwnd);
256     EnableWindow (hparwnd, TRUE);
257     SetActiveWindow (NULL);
258    
259     // show message for a fixed amount of time
260     SetTimer (hwnd, BT_TIMER_IDENTIFIER, millis, popup_timer_proc);
261    
262     return hwnd;
263     }
264    
265    
266     /* Show message at the default position for 5 seconds */
267     void
268     show_balloon_msg (HWND hparwnd, LPCTSTR string, LPCTSTR icon_name)
269     {
270     show_balloon_msg_pos (hparwnd, 5000, 0, 0, string ,icon_name);
271     }
272    
273    
274     /* Disable the message box (hide the window) */
275     void
276     balloon_msg_disable (void)
277     {
278     ShowWindow (glob_msg.hwnd, SW_HIDE);
279     }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26