OSDN Git Service

Initial Import
[nethackexpress/trunk.git] / win / win32 / mhrip.c
1 /* Copyright (C) 2001 by Alex Kompel <shurikk@pacbell.net> */
2 /* NetHack may be freely redistributed.  See license for details. */
3
4 #include "winMS.h"
5 #include "resource.h"
6 #include "mhrip.h"
7 #include "mhmsg.h"
8 #include "mhfont.h"
9
10 #define RIP_WIDTH       400
11 #define RIP_HEIGHT      200
12
13 #define RIP_GRAVE_HEIGHT        120
14 #define RIP_GRAVE_WIDTH         115
15 #define RIP_GRAVE_X             90
16 #define RIP_GRAVE_Y             60
17
18 #define RIP_OFFSET_X            10
19 #define RIP_OFFSET_Y            10
20
21 PNHWinApp GetNHApp(void);
22
23 typedef struct mswin_nethack_text_window {
24         HANDLE  rip_bmp;
25         TCHAR*  window_text;
26         TCHAR*  rip_text;
27 } NHRIPWindow, *PNHRIPWindow;
28
29 BOOL CALLBACK NHRIPWndProc(HWND, UINT, WPARAM, LPARAM);
30 static void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam);
31
32 HWND mswin_init_RIP_window () {
33         HWND ret;
34         PNHRIPWindow data;
35
36         ret = CreateDialog(
37                         GetNHApp()->hApp,
38                         MAKEINTRESOURCE(IDD_NHRIP),
39                         GetNHApp()->hMainWnd,
40                         NHRIPWndProc
41         );
42         if( !ret ) panic("Cannot create rip window");
43
44         data = (PNHRIPWindow)malloc(sizeof(NHRIPWindow));
45         if( !data ) panic("out of memory");
46
47         ZeroMemory(data, sizeof(NHRIPWindow));
48         SetWindowLong(ret, GWL_USERDATA, (LONG)data);
49         return ret;
50 }
51
52 void mswin_display_RIP_window (HWND hWnd)
53 {
54         MSG msg;
55         RECT rt;
56         PNHRIPWindow data;
57         HWND mapWnd;
58         RECT riprt;
59         RECT clientrect;
60         RECT textrect;
61         HDC hdc;
62         HFONT OldFont;
63
64         data = (PNHRIPWindow)GetWindowLong(hWnd, GWL_USERDATA);
65
66         GetNHApp()->hPopupWnd = hWnd;
67         mapWnd = mswin_hwnd_from_winid(WIN_MAP);
68         if( !IsWindow(mapWnd) ) mapWnd = GetNHApp()->hMainWnd;
69         GetWindowRect(mapWnd, &rt);
70         GetWindowRect(hWnd, &riprt);
71         GetClientRect (hWnd, &clientrect);
72         textrect = clientrect;
73         textrect.top += RIP_OFFSET_Y;
74         textrect.left += RIP_OFFSET_X;
75         textrect.right -= RIP_OFFSET_X;
76         if (data->window_text)
77         {
78             hdc = GetDC (hWnd);
79             OldFont = SelectObject (hdc, mswin_get_font(NHW_TEXT, 0, hdc, FALSE));
80             DrawText (hdc, data->window_text, strlen(data->window_text), &textrect,
81                 DT_LEFT | DT_NOPREFIX | DT_CALCRECT);
82             SelectObject (hdc, OldFont);
83             ReleaseDC(hWnd, hdc);
84         }
85         if (textrect.right - textrect.left > RIP_WIDTH)
86             clientrect.right = textrect.right + RIP_OFFSET_X - clientrect.right;
87         else
88             clientrect.right = textrect.left + 2 * RIP_OFFSET_X + RIP_WIDTH - clientrect.right;
89         clientrect.bottom = textrect.bottom + RIP_HEIGHT + RIP_OFFSET_Y - clientrect.bottom;
90         GetWindowRect (GetDlgItem(hWnd, IDOK), &textrect);
91         textrect.right -= textrect.left;
92         textrect.bottom -= textrect.top;
93         clientrect.bottom += textrect.bottom + RIP_OFFSET_Y;
94         riprt.right -= riprt.left;
95         riprt.bottom -= riprt.top;
96         riprt.right += clientrect.right;
97         riprt.bottom += clientrect.bottom;
98         rt.left += (rt.right - rt.left - riprt.right) / 2;
99         rt.top += (rt.bottom - rt.top - riprt.bottom) / 2;
100
101         MoveWindow(hWnd, rt.left, rt.top, riprt.right, riprt.bottom, TRUE);
102         GetClientRect (hWnd, &clientrect);
103         MoveWindow (GetDlgItem(hWnd, IDOK),
104             (clientrect.right - clientrect.left - textrect.right) / 2,
105             clientrect.bottom - textrect.bottom - RIP_OFFSET_Y, textrect.right, textrect.bottom, TRUE);
106         ShowWindow(hWnd, SW_SHOW);
107
108         while( IsWindow(hWnd) &&
109                    GetMessage(&msg, NULL, 0, 0)!=0 ) {
110                 if( !IsDialogMessage(hWnd, &msg) ) {
111                         TranslateMessage(&msg);
112                         DispatchMessage(&msg);
113                 }
114         }
115
116         GetNHApp()->hPopupWnd = NULL;
117 }
118
119 BOOL CALLBACK NHRIPWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
120 {
121         HDC hdc;
122         PNHRIPWindow data;
123
124         data = (PNHRIPWindow)GetWindowLong(hWnd, GWL_USERDATA);
125         switch (message)
126         {
127         case WM_INITDIALOG:
128             /* set text control font */
129                 hdc = GetDC(hWnd);
130                 SendMessage(hWnd, WM_SETFONT,
131                         (WPARAM)mswin_get_font(NHW_TEXT, ATR_NONE, hdc, FALSE), 0);
132                 ReleaseDC(hWnd, hdc);
133
134                 SetFocus(GetDlgItem(hWnd, IDOK));
135         return FALSE;
136
137         case WM_MSNH_COMMAND:
138                 onMSNHCommand(hWnd, wParam, lParam);
139         break;
140
141         case WM_PAINT:
142         {
143                 int bitmap_offset;
144                 RECT clientrect;
145                 RECT textrect;
146                 HDC hdcBitmap;
147                 HANDLE OldBitmap;
148                 PAINTSTRUCT ps;
149                 HFONT OldFont;
150
151                 hdc = BeginPaint (hWnd, &ps);
152                 OldFont = SelectObject (hdc, mswin_get_font(NHW_TEXT, 0, hdc, FALSE));
153                 hdcBitmap = CreateCompatibleDC(hdc);
154                 SetBkMode (hdc, TRANSPARENT);
155                 GetClientRect (hWnd, &clientrect);
156                 textrect = clientrect;
157                 textrect.top += RIP_OFFSET_Y;
158                 textrect.left += RIP_OFFSET_X;
159                 textrect.right -= RIP_OFFSET_X;
160                 if (data->window_text)
161                 {
162                         DrawText (hdc, data->window_text, strlen(data->window_text), &textrect,
163                                 DT_LEFT | DT_NOPREFIX | DT_CALCRECT);
164                         DrawText (hdc, data->window_text, strlen(data->window_text), &textrect,
165                                 DT_LEFT | DT_NOPREFIX);
166                 }
167                 OldBitmap = SelectObject(hdcBitmap, GetNHApp()->bmpRip);
168                 SetBkMode (hdc, OPAQUE);
169                 bitmap_offset = (textrect.right - textrect.left - RIP_WIDTH) / 2;
170                 BitBlt (hdc, textrect.left + bitmap_offset, textrect.bottom, RIP_WIDTH,
171                         RIP_HEIGHT, hdcBitmap, 0, 0, SRCCOPY);
172                 SetBkMode (hdc, TRANSPARENT);
173                 if (data->rip_text)
174                 {
175                         textrect.left += RIP_GRAVE_X + bitmap_offset;
176                         textrect.top = textrect.bottom + RIP_GRAVE_Y;
177                         textrect.right = textrect.left + RIP_GRAVE_WIDTH;
178                         textrect.bottom = textrect.top + RIP_GRAVE_HEIGHT;
179                         DrawText (hdc, data->rip_text, strlen(data->rip_text), &textrect,
180                                 DT_CENTER | DT_VCENTER | DT_NOPREFIX | DT_WORDBREAK);
181                 }
182                 SelectObject (hdcBitmap, OldBitmap);
183                 SelectObject (hdc, OldFont);
184                 DeleteDC (hdcBitmap);
185                 EndPaint (hWnd, &ps);
186         }
187         break;
188
189         case WM_COMMAND:
190                 switch (LOWORD(wParam))
191         {
192           case IDOK:
193                         mswin_window_mark_dead(mswin_winid_from_handle(hWnd));
194                         if( GetNHApp()->hMainWnd==hWnd )
195                                 GetNHApp()->hMainWnd=NULL;
196                         DestroyWindow(hWnd);
197                         SetFocus(GetNHApp()->hMainWnd);
198                         return TRUE;
199                 }
200         break;
201
202         case WM_CLOSE:
203             /* if we get this here, we saved the bones so we can just force a quit */
204
205             mswin_window_mark_dead(mswin_winid_from_handle(hWnd));
206             if( GetNHApp()->hMainWnd==hWnd )
207                 GetNHApp()->hMainWnd=NULL;
208             DestroyWindow(hWnd);
209             SetFocus(GetNHApp()->hMainWnd);
210             program_state.stopprint++;
211             return TRUE;
212
213         case WM_DESTROY:
214                 if( data ) {
215                         if( data->window_text ) free(data->window_text);
216                         if( data->rip_text ) free(data->rip_text);
217                         if (data->rip_bmp != NULL) DeleteObject(data->rip_bmp);
218                         free(data);
219                         SetWindowLong(hWnd, GWL_USERDATA, (LONG)0);
220                 }
221         break;
222
223         }
224         return FALSE;
225 }
226
227 void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
228 {
229         PNHRIPWindow data;
230         static int InRipText = 1;
231         data = (PNHRIPWindow)GetWindowLong(hWnd, GWL_USERDATA);
232         switch( wParam ) {
233                 case MSNH_MSG_PUTSTR: {
234                         PMSNHMsgPutstr msg_data = (PMSNHMsgPutstr)lParam;
235                         TCHAR   wbuf[BUFSZ];
236                         size_t text_size;
237
238                         if( !data->window_text ) {
239                                 text_size = strlen(msg_data->text) + 4;
240                                 data->window_text = (TCHAR*)malloc(text_size*sizeof(data->window_text[0]));
241                                 ZeroMemory(data->window_text, text_size*sizeof(data->window_text[0]));
242                         } else {
243                                 text_size = _tcslen(data->window_text) + strlen(msg_data->text) + 4;
244                                 data->window_text = (TCHAR*)realloc(data->window_text, text_size*sizeof(data->window_text[0]));
245                         }
246                         if( !data->window_text ) break;
247
248                         _tcscat(data->window_text, NH_A2W(msg_data->text, wbuf, BUFSZ));
249                         _tcscat(data->window_text, TEXT("\r\n"));
250                         break;
251                 }
252                 case MSNH_MSG_DIED:
253                 {
254                         data->rip_text = data->window_text;
255                         data->window_text = NULL;
256                         break;
257                 }
258
259         }
260 }
261
262 void mswin_finish_rip_text(winid wid)
263 {
264         SendMessage (mswin_hwnd_from_winid(wid), WM_MSNH_COMMAND,  MSNH_MSG_DIED, 0);
265 }