4 * Copyright 1996 Ulrich Schmid <uschmid@mail.hh.provi.de>
16 VOID
LIBWINE_Register_De(void);
17 VOID
LIBWINE_Register_En(void);
18 VOID
LIBWINE_Register_Fi(void);
19 VOID
LIBWINE_Register_Fr(void);
20 VOID
LIBWINE_Register_Hu(void);
21 VOID
LIBWINE_Register_It(void);
22 VOID
LIBWINE_Register_Ko(void);
23 VOID
LIBWINE_Register_Sw(void);
24 VOID
LIBWINE_Register_Va(void);
26 static BOOL
WINHELP_RegisterWinClasses();
27 static LRESULT
WINHELP_MainWndProc(HWND
, UINT
, WPARAM
, LPARAM
);
28 static LRESULT
WINHELP_TextWndProc(HWND
, UINT
, WPARAM
, LPARAM
);
29 static LRESULT
WINHELP_ButtonBoxWndProc(HWND
, UINT
, WPARAM
, LPARAM
);
30 static VOID
WINHELP_CheckPopup(UINT
);
31 static BOOL
WINHELP_SplitLines(HWND hWnd
, LPSIZE
);
32 static VOID
WINHELP_InitFonts(HWND hWnd
);
33 static VOID
WINHELP_DeleteLines(WINHELP_WINDOW
*);
34 static VOID
WINHELP_DeleteWindow(WINHELP_WINDOW
*);
35 static VOID
WINHELP_SetupText(HWND hWnd
);
36 static BOOL
WINHELP_AppendText(WINHELP_LINE
***, WINHELP_LINE_PART
***,
37 LPSIZE
, LPSIZE
, INT
*, INT
, LPCSTR
, UINT
,
38 HFONT
, COLORREF
, HLPFILE_LINK
*);
40 WINHELP_GLOBALS Globals
= {3, 0, 0, 0, 0, 0};
42 static BOOL MacroTest
= FALSE
;
44 /***********************************************************************
49 int PASCAL
WinMain (HANDLE hInstance
, HANDLE prev
, LPSTR cmdline
, int show
)
51 LPCSTR opt_lang
= "En";
57 #if defined(WINELIB) && !defined(HAVE_WINE_CONSTRUCTOR)
58 /* Register resources */
59 LIBWINE_Register_De();
60 LIBWINE_Register_En();
61 LIBWINE_Register_Fi();
62 LIBWINE_Register_Fr();
63 LIBWINE_Register_It();
64 LIBWINE_Register_Ko();
65 LIBWINE_Register_Hu();
66 LIBWINE_Register_Va();
69 Globals
.hInstance
= hInstance
;
72 while (*cmdline
&& (*cmdline
== ' ' || *cmdline
== '-'))
76 if (*cmdline
++ == ' ') continue;
79 if (option
) cmdline
++;
80 while (*cmdline
&& *cmdline
== ' ') cmdline
++;
86 while (*cmdline
&& *cmdline
!= ' ') cmdline
++;
87 if (*cmdline
) *cmdline
++ = '\0';
88 lHash
= HLPFILE_Hash(topic_id
);
93 Globals
.wVersion
= option
- '0';
103 opt_lang
= Languages
[Options
.language
].name
;
106 /* Find language specific string table */
107 for (langnum
= 0; langnum
<= MAX_LANGUAGE_NUMBER
; langnum
++)
109 Globals
.wStringTableOffset
= langnum
* 0x100;
110 if (LoadString(hInstance
, IDS_LANGUAGE_ID
, lang
, sizeof(lang
)) &&
111 !lstrcmp(opt_lang
, lang
))
114 if (langnum
> MAX_LANGUAGE_NUMBER
)
116 /* Find fallback language */
117 for (langnum
= 0; langnum
<= MAX_LANGUAGE_NUMBER
; langnum
++)
119 Globals
.wStringTableOffset
= langnum
* 0x100;
120 if (LoadString(hInstance
, IDS_LANGUAGE_ID
, lang
, sizeof(lang
)))
123 if (langnum
> MAX_LANGUAGE_NUMBER
)
125 MessageBox(0, "No language found", "FATAL ERROR", MB_OK
);
130 /* Change Resource names */
131 lstrcpyn(STRING_MENU_Xx
+ lstrlen(STRING_MENU_Xx
) - 2, lang
, 3);
133 /* Create primary window */
134 WINHELP_RegisterWinClasses();
135 WINHELP_CreateHelpWindow(cmdline
, lHash
, "main", FALSE
, NULL
, NULL
, show
);
138 while (GetMessage (&msg
, 0, 0, 0))
140 TranslateMessage (&msg
);
141 DispatchMessage (&msg
);
146 /***********************************************************************
151 static BOOL
WINHELP_RegisterWinClasses()
153 WNDCLASS class_main
, class_button_box
, class_text
, class_shadow
;
155 class_main
.style
= CS_HREDRAW
| CS_VREDRAW
;
156 class_main
.lpfnWndProc
= WINHELP_MainWndProc
;
157 class_main
.cbClsExtra
= 0;
158 class_main
.cbWndExtra
= sizeof(LONG
);
159 class_main
.hInstance
= Globals
.hInstance
;
160 class_main
.hIcon
= LoadIcon (0, IDI_APPLICATION
);
161 class_main
.hCursor
= LoadCursor (0, IDC_ARROW
);
162 class_main
.hbrBackground
= GetStockObject (WHITE_BRUSH
);
163 class_main
.lpszMenuName
= 0;
164 class_main
.lpszClassName
= MAIN_WIN_CLASS_NAME
;
166 class_button_box
= class_main
;
167 class_button_box
.lpfnWndProc
= WINHELP_ButtonBoxWndProc
;
168 class_button_box
.hbrBackground
= GetStockObject(GRAY_BRUSH
);
169 class_button_box
.lpszClassName
= BUTTON_BOX_WIN_CLASS_NAME
;
171 class_text
= class_main
;
172 class_text
.lpfnWndProc
= WINHELP_TextWndProc
;
173 class_text
.lpszClassName
= TEXT_WIN_CLASS_NAME
;
175 class_shadow
= class_main
;
176 class_shadow
.lpfnWndProc
= DefWindowProc
;
177 class_shadow
.hbrBackground
= GetStockObject(GRAY_BRUSH
);
178 class_shadow
.lpszClassName
= SHADOW_WIN_CLASS_NAME
;
180 return (RegisterClass(&class_main
) &&
181 RegisterClass(&class_button_box
) &&
182 RegisterClass(&class_text
) &&
183 RegisterClass(&class_shadow
));
186 /***********************************************************************
188 * WINHELP_CreateHelpWindow
191 VOID
WINHELP_CreateHelpWindow(LPCSTR lpszFile
, LONG lHash
, LPCSTR lpszWindow
,
192 BOOL bPopup
, HWND hParentWnd
, LPPOINT mouse
, INT nCmdShow
)
194 CHAR szCaption
[MAX_STRING_LEN
];
195 CHAR szContents
[MAX_STRING_LEN
];
196 CHAR szSearch
[MAX_STRING_LEN
];
197 CHAR szBack
[MAX_STRING_LEN
];
198 CHAR szHistory
[MAX_STRING_LEN
];
199 SIZE size
= {CW_USEDEFAULT
, CW_USEDEFAULT
};
200 POINT origin
= {240, 0};
203 WINHELP_WINDOW
*win
, *oldwin
;
205 HLPFILE_MACRO
*macro
;
211 else if (!lpszWindow
|| !lpszWindow
[0])
212 lpszWindow
= Globals
.active_win
->lpszName
;
213 bPrimary
= lpszWindow
&& !lstrcmpi(lpszWindow
, "main");
218 page
= lHash
? HLPFILE_PageByHash(lpszFile
, lHash
) : HLPFILE_Contents(lpszFile
);
220 /* Add Suffix `.hlp' */
221 if (!page
&& lstrcmpi(lpszFile
+ strlen(lpszFile
) - 4, ".hlp"))
223 CHAR szFile_hlp
[MAX_PATHNAME_LEN
];
225 lstrcpyn(szFile_hlp
, lpszFile
, sizeof(szFile_hlp
) - 4);
226 szFile_hlp
[sizeof(szFile_hlp
) - 5] = '\0';
227 lstrcat(szFile_hlp
, ".hlp");
229 page
= lHash
? HLPFILE_PageByHash(szFile_hlp
, lHash
) : HLPFILE_Contents(szFile_hlp
);
232 WINHELP_MessageBoxIDS_s(IDS_HLPFILE_ERROR_s
, lpszFile
, IDS_ERROR
, MB_OK
);
233 if (Globals
.win_list
) return;
239 /* Calculate horizontal size and position of a popup window */
243 GetWindowRect(hParentWnd
, &parent_rect
);
244 size
.cx
= (parent_rect
.right
- parent_rect
.left
) / 2;
247 ClientToScreen(hParentWnd
, &origin
);
248 origin
.x
-= size
.cx
/ 2;
249 origin
.x
= MIN(origin
.x
, GetSystemMetrics(SM_CXSCREEN
) - size
.cx
);
250 origin
.x
= MAX(origin
.x
, 0);
253 /* Initialize WINHELP_WINDOW struct */
254 handle
= GlobalAlloc(GMEM_FIXED
, sizeof(WINHELP_WINDOW
) +
255 (lpszWindow
? strlen(lpszWindow
) + 1 : 0));
257 win
= GlobalLock(handle
);
259 win
->next
= Globals
.win_list
;
260 Globals
.win_list
= win
;
263 ptr
= GlobalLock(handle
);
264 ptr
+= sizeof(WINHELP_WINDOW
);
265 lstrcpy(ptr
, (LPSTR
) lpszWindow
);
268 else win
->lpszName
= NULL
;
270 win
->first_button
= 0;
273 win
->hButtonBoxWnd
= 0;
277 Globals
.active_win
= win
;
279 /* Initialize default pushbuttons */
280 if (MacroTest
&& !bPopup
)
281 MACRO_CreateButton("BTN_TEST", "&Test", "MacroTest");
282 if (bPrimary
&& page
)
284 LoadString(Globals
.hInstance
, IDS_CONTENTS
, szContents
, sizeof(szContents
));
285 LoadString(Globals
.hInstance
, IDS_SEARCH
, szSearch
, sizeof(szSearch
));
286 LoadString(Globals
.hInstance
, IDS_BACK
, szBack
, sizeof(szBack
));
287 LoadString(Globals
.hInstance
, IDS_HISTORY
, szHistory
, sizeof(szHistory
));
288 MACRO_CreateButton("BTN_CONTENTS", szContents
, "Contents()");
289 MACRO_CreateButton("BTN_SEARCH", szSearch
, "Search()");
290 MACRO_CreateButton("BTN_BACK", szBack
, "Back()");
291 MACRO_CreateButton("BTN_HISTORY", szHistory
, "History()");
294 /* Initialize file specific pushbuttons */
296 for (macro
= page
->file
->first_macro
; macro
; macro
= macro
->next
)
297 MACRO_ExecuteMacro(macro
->lpszMacro
);
299 /* Reuse existing window */
301 for (oldwin
= win
->next
; oldwin
; oldwin
= oldwin
->next
)
302 if (oldwin
->lpszName
&& !lstrcmpi(oldwin
->lpszName
, lpszWindow
))
304 WINHELP_BUTTON
*button
;
306 win
->hMainWnd
= oldwin
->hMainWnd
;
307 win
->hButtonBoxWnd
= oldwin
->hButtonBoxWnd
;
308 win
->hTextWnd
= oldwin
->hTextWnd
;
309 oldwin
->hMainWnd
= oldwin
->hButtonBoxWnd
= oldwin
->hTextWnd
= 0;
311 SetWindowLong(win
->hMainWnd
, 0, (LONG
) win
);
312 SetWindowLong(win
->hButtonBoxWnd
, 0, (LONG
) win
);
313 SetWindowLong(win
->hTextWnd
, 0, (LONG
) win
);
315 WINHELP_InitFonts(win
->hMainWnd
);
318 SetWindowText(win
->hMainWnd
, page
->file
->lpszTitle
);
321 WINHELP_SetupText(win
->hTextWnd
);
322 InvalidateRect(win
->hTextWnd
, NULL
, TRUE
);
323 SendMessage(win
->hMainWnd
, WM_USER
, 0, 0);
324 UpdateWindow(win
->hTextWnd
);
327 for (button
= oldwin
->first_button
; button
; button
= button
->next
)
328 DestroyWindow(button
->hWnd
);
330 WINHELP_DeleteWindow(oldwin
);
334 /* Create main Window */
335 if (!page
) LoadString(Globals
.hInstance
, IDS_WINE_HELP
, szCaption
, sizeof(szCaption
));
336 hWnd
= CreateWindow (bPopup
? TEXT_WIN_CLASS_NAME
: MAIN_WIN_CLASS_NAME
,
337 page
? page
->file
->lpszTitle
: szCaption
,
338 bPopup
? WS_POPUPWINDOW
| WS_BORDER
: WS_OVERLAPPEDWINDOW
,
339 origin
.x
, origin
.y
, size
.cx
, size
.cy
,
340 0, bPrimary
? LoadMenu(Globals
.hInstance
, STRING_MENU_Xx
) : 0,
341 Globals
.hInstance
, win
);
343 ShowWindow (hWnd
, nCmdShow
);
347 /***********************************************************************
349 * WINHELP_MainWndProc
352 static LRESULT
WINHELP_MainWndProc (HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
355 WINHELP_BUTTON
*button
;
356 RECT rect
, button_box_rect
;
359 WINHELP_CheckPopup(msg
);
364 win
= (WINHELP_WINDOW
*) ((LPCREATESTRUCT
) lParam
)->lpCreateParams
;
365 SetWindowLong(hWnd
, 0, (LONG
) win
);
366 win
->hMainWnd
= hWnd
;
370 win
= (WINHELP_WINDOW
*) GetWindowLong(hWnd
, 0);
372 /* Create button box and text Window */
373 CreateWindow(BUTTON_BOX_WIN_CLASS_NAME
, "", WS_CHILD
| WS_VISIBLE
,
374 0, 0, 0, 0, hWnd
, 0, Globals
.hInstance
, win
);
376 CreateWindow(TEXT_WIN_CLASS_NAME
, "", WS_CHILD
| WS_VISIBLE
,
377 0, 0, 0, 0, hWnd
, 0, Globals
.hInstance
, win
);
381 case WM_WINDOWPOSCHANGED
:
382 win
= (WINHELP_WINDOW
*) GetWindowLong(hWnd
, 0);
383 GetClientRect(hWnd
, &rect
);
385 /* Update button box and text Window */
386 SetWindowPos(win
->hButtonBoxWnd
, HWND_TOP
,
388 rect
.right
- rect
.left
,
389 rect
.bottom
- rect
.top
, 0);
391 GetWindowRect(win
->hButtonBoxWnd
, &button_box_rect
);
392 text_top
= rect
.top
+ button_box_rect
.bottom
- button_box_rect
.top
;
394 SetWindowPos(win
->hTextWnd
, HWND_TOP
,
396 rect
.right
- rect
.left
,
397 rect
.bottom
- text_top
, 0);
402 Globals
.active_win
= win
= (WINHELP_WINDOW
*) GetWindowLong(hWnd
, 0);
406 case WH_OPEN
: MACRO_FileOpen(); break;
407 case WH_PRINT
: MACRO_Print(); break;
408 case WH_PRINTER_SETUP
: MACRO_PrinterSetup(); break;
409 case WH_EXIT
: MACRO_Exit(); break;
412 case WH_COPY_DIALOG
: MACRO_CopyDialog(); break;
413 case WH_ANNOTATE
: MACRO_Annotate(); break;
416 case WH_BOOKMARK_DEFINE
: MACRO_BookmarkDefine(); break;
419 case WH_HELP_ON_HELP
: MACRO_HelpOn(); break;
420 case WH_HELP_ON_TOP
: MACRO_HelpOnTop(); break;
423 case WH_ABOUT
: MACRO_About(); break;
426 ShellAbout(hWnd
, "WINE", "Help", 0);
431 for (button
= win
->first_button
; button
; button
= button
->next
)
432 if (wParam
== button
->wParam
) break;
434 MACRO_ExecuteMacro(button
->lpszMacro
);
436 WINHELP_MessageBoxIDS(IDS_NOT_IMPLEMENTED
, IDS_ERROR
, MB_OK
);
442 return DefWindowProc (hWnd
, msg
, wParam
, lParam
);
445 /***********************************************************************
447 * WINHELP_ButtonBoxWndProc
450 static LRESULT
WINHELP_ButtonBoxWndProc (HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
454 WINHELP_BUTTON
*button
;
458 WINHELP_CheckPopup(msg
);
463 win
= (WINHELP_WINDOW
*) ((LPCREATESTRUCT
) lParam
)->lpCreateParams
;
464 SetWindowLong(hWnd
, 0, (LONG
) win
);
465 win
->hButtonBoxWnd
= hWnd
;
468 case WM_WINDOWPOSCHANGING
:
469 winpos
= (WINDOWPOS
*) lParam
;
470 win
= (WINHELP_WINDOW
*) GetWindowLong(hWnd
, 0);
475 for (button
= win
->first_button
; button
; button
= button
->next
)
480 button
->hWnd
= CreateWindow(STRING_BUTTON
, (LPSTR
) button
->lpszName
,
481 WS_CHILD
| WS_VISIBLE
| BS_PUSHBUTTON
,
483 hWnd
, (HMENU
) button
->wParam
,
484 Globals
.hInstance
, 0);
485 hDc
= GetDC(button
->hWnd
);
486 GetTextExtentPoint(hDc
, button
->lpszName
,
487 lstrlen(button
->lpszName
), &textsize
);
488 ReleaseDC(button
->hWnd
, hDc
);
490 button_size
.cx
= MAX(button_size
.cx
, textsize
.cx
+ BUTTON_CX
);
491 button_size
.cy
= MAX(button_size
.cy
, textsize
.cy
+ BUTTON_CY
);
496 for (button
= win
->first_button
; button
; button
= button
->next
)
498 SetWindowPos(button
->hWnd
, HWND_TOP
, x
, y
, button_size
.cx
, button_size
.cy
, 0);
500 if (x
+ 2 * button_size
.cx
<= winpos
->cx
)
503 x
= 0, y
+= button_size
.cy
;
505 winpos
->cy
= y
+ (x
? button_size
.cy
: 0);
509 SendMessage(GetParent(hWnd
), msg
, wParam
, lParam
);
513 return(DefWindowProc(hWnd
, msg
, wParam
, lParam
));
516 /***********************************************************************
518 * WINHELP_TextWndProc
521 static LRESULT
WINHELP_TextWndProc (HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
525 WINHELP_LINE_PART
*part
;
534 if (msg
!= WM_LBUTTONDOWN
)
535 WINHELP_CheckPopup(msg
);
540 win
= (WINHELP_WINDOW
*) ((LPCREATESTRUCT
) lParam
)->lpCreateParams
;
541 SetWindowLong(hWnd
, 0, (LONG
) win
);
542 win
->hTextWnd
= hWnd
;
543 if (!win
->lpszName
) Globals
.hPopupWnd
= win
->hMainWnd
= hWnd
;
544 WINHELP_InitFonts(hWnd
);
548 win
= (WINHELP_WINDOW
*) GetWindowLong(hWnd
, 0);
550 /* Calculate vertical size and position of a popup window */
554 RECT old_window_rect
;
555 RECT old_client_rect
;
556 SIZE old_window_size
;
557 SIZE old_client_size
;
558 SIZE new_client_size
;
559 SIZE new_window_size
;
561 GetWindowRect(hWnd
, &old_window_rect
);
562 origin
.x
= old_window_rect
.left
;
563 origin
.y
= old_window_rect
.top
;
564 old_window_size
.cx
= old_window_rect
.right
- old_window_rect
.left
;
565 old_window_size
.cy
= old_window_rect
.bottom
- old_window_rect
.top
;
567 GetClientRect(hWnd
, &old_client_rect
);
568 old_client_size
.cx
= old_client_rect
.right
- old_client_rect
.left
;
569 old_client_size
.cy
= old_client_rect
.bottom
- old_client_rect
.top
;
571 new_client_size
= old_client_size
;
572 WINHELP_SplitLines(hWnd
, &new_client_size
);
574 if (origin
.y
+ POPUP_YDISTANCE
+ new_client_size
.cy
<= GetSystemMetrics(SM_CYSCREEN
))
575 origin
.y
+= POPUP_YDISTANCE
;
577 origin
.y
-= POPUP_YDISTANCE
+ new_client_size
.cy
;
579 new_window_size
.cx
= old_window_size
.cx
- old_client_size
.cx
+ new_client_size
.cx
;
580 new_window_size
.cy
= old_window_size
.cy
- old_client_size
.cy
+ new_client_size
.cy
;
583 CreateWindow(SHADOW_WIN_CLASS_NAME
, "", WS_POPUP
| WS_VISIBLE
,
584 origin
.x
+ SHADOW_DX
, origin
.y
+ SHADOW_DY
,
585 new_window_size
.cx
, new_window_size
.cy
,
586 0, 0, Globals
.hInstance
, 0);
588 SetWindowPos(hWnd
, HWND_TOP
, origin
.x
, origin
.y
,
589 new_window_size
.cx
, new_window_size
.cy
,
590 SWP_NOZORDER
| SWP_NOACTIVATE
);
591 ShowWindow(win
->hShadowWnd
, SW_NORMAL
);
595 case WM_WINDOWPOSCHANGED
:
596 winpos
= (WINDOWPOS
*) lParam
;
597 if (!(winpos
->flags
& SWP_NOSIZE
)) WINHELP_SetupText(hWnd
);
605 INT CurPos
= GetScrollPos(hWnd
, SB_VERT
);
606 GetScrollRange(hWnd
, SB_VERT
, &Min
, &Max
);
607 GetClientRect(hWnd
, &rect
);
609 switch (wParam
& 0xffff)
612 case SB_THUMBPOSITION
: CurPos
= wParam
>> 16; break;
613 case SB_TOP
: CurPos
= Min
; break;
614 case SB_BOTTOM
: CurPos
= Max
; break;
615 case SB_PAGEUP
: CurPos
-= (rect
.bottom
- rect
.top
) / 2; break;
616 case SB_PAGEDOWN
: CurPos
+= (rect
.bottom
- rect
.top
) / 2; break;
617 case SB_LINEUP
: CurPos
-= GetSystemMetrics(SM_CXVSCROLL
); break;
618 case SB_LINEDOWN
: CurPos
+= GetSystemMetrics(SM_CXVSCROLL
); break;
619 default: update
= FALSE
;
623 INT dy
= GetScrollPos(hWnd
, SB_VERT
) - CurPos
;
624 SetScrollPos(hWnd
, SB_VERT
, CurPos
, TRUE
);
625 ScrollWindow(hWnd
, 0, dy
, NULL
, NULL
);
632 hDc
= BeginPaint (hWnd
, &ps
);
633 win
= (WINHELP_WINDOW
*) GetWindowLong(hWnd
, 0);
634 scroll_pos
= GetScrollPos(hWnd
, SB_VERT
);
636 for (line
= win
->first_line
; line
; line
= line
->next
)
637 for (part
= &line
->first_part
; part
; part
= part
->next
)
639 SelectObject(hDc
, part
->hFont
);
640 SetTextColor(hDc
, part
->color
);
641 TextOut(hDc
, part
->rect
.left
, part
->rect
.top
- scroll_pos
,
642 (LPSTR
) part
->lpsText
, part
->wTextLen
);
645 EndPaint (hWnd
, &ps
);
649 win
= (WINHELP_WINDOW
*) GetWindowLong(hWnd
, 0);
650 scroll_pos
= GetScrollPos(hWnd
, SB_VERT
);
652 hPopupWnd
= Globals
.hPopupWnd
;
653 Globals
.hPopupWnd
= 0;
655 mouse
.x
= LOWORD(lParam
);
656 mouse
.y
= HIWORD(lParam
);
657 for (line
= win
->first_line
; line
; line
= line
->next
)
658 for (part
= &line
->first_part
; part
; part
= part
->next
)
659 if (part
->link
.lpszPath
&&
660 part
->rect
.left
<= mouse
.x
&&
661 part
->rect
.right
>= mouse
.x
&&
662 part
->rect
.top
<= mouse
.y
+ scroll_pos
&&
663 part
->rect
.bottom
>= mouse
.y
+ scroll_pos
)
664 WINHELP_CreateHelpWindow(part
->link
.lpszPath
, part
->link
.lHash
, NULL
,
665 part
->link
.bPopup
, hWnd
, &mouse
, SW_NORMAL
);
667 DestroyWindow(hPopupWnd
);
671 win
= (WINHELP_WINDOW
*) GetWindowLong(hWnd
, 0);
673 if (hWnd
== Globals
.hPopupWnd
) Globals
.hPopupWnd
= 0;
675 bExit
= (Globals
.wVersion
>= 4 && !lstrcmpi(win
->lpszName
, "main"));
677 WINHELP_DeleteWindow(win
);
679 if (bExit
) MACRO_Exit();
681 if (!Globals
.win_list
)
686 return DefWindowProc (hWnd
, msg
, wParam
, lParam
);
689 /***********************************************************************
694 static VOID
WINHELP_SetupText(HWND hWnd
)
696 HDC hDc
= GetDC(hWnd
);
700 ShowScrollBar(hWnd
, SB_VERT
, FALSE
);
701 if (!WINHELP_SplitLines(hWnd
, NULL
))
703 ShowScrollBar(hWnd
, SB_VERT
, TRUE
);
704 GetClientRect(hWnd
, &rect
);
706 WINHELP_SplitLines(hWnd
, &newsize
);
707 SetScrollRange(hWnd
, SB_VERT
, 0, rect
.top
+ newsize
.cy
- rect
.bottom
, TRUE
);
709 else SetScrollPos(hWnd
, SB_VERT
, 0, FALSE
);
711 ReleaseDC(hWnd
, hDc
);
714 /***********************************************************************
719 static BOOL
WINHELP_SplitLines(HWND hWnd
, LPSIZE newsize
)
721 WINHELP_WINDOW
*win
= (WINHELP_WINDOW
*) GetWindowLong(hWnd
, 0);
722 HLPFILE_PARAGRAPH
*p
;
723 WINHELP_LINE
**line
= &win
->first_line
;
724 WINHELP_LINE_PART
**part
= 0;
730 if (newsize
) newsize
->cx
= newsize
->cy
= 0;
732 if (!win
->page
) return TRUE
;
734 WINHELP_DeleteLines(win
);
736 GetClientRect(hWnd
, &rect
);
738 rect
.top
+= INTERNAL_BORDER_WIDTH
;
739 rect
.left
+= INTERNAL_BORDER_WIDTH
;
740 rect
.right
-= INTERNAL_BORDER_WIDTH
;
741 rect
.bottom
-= INTERNAL_BORDER_WIDTH
;
745 space
.cx
= rect
.left
;
749 for (p
= win
->page
->first_paragraph
; p
; p
= p
->next
)
752 SIZE textsize
= {0, 0};
753 LPCSTR text
= p
->lpszText
;
754 UINT len
= strlen(text
);
757 UINT wFont
= (p
->wFont
< win
->fonts_len
) ? p
->wFont
: 0;
758 BOOL bUnderline
= p
->link
&& !p
->link
->bPopup
;
759 HFONT hFont
= win
->fonts
[wFont
][bUnderline
? 1 : 0];
761 COLORREF color
= RGB(0, 0, 0);
762 if (p
->link
) color
= RGB(0, 0x80, 0);
763 if (p
->bDebug
) color
= RGB(0xff, 0, 0);
765 SelectObject(hDc
, hFont
);
767 GetTextMetrics (hDc
, &tm
);
771 indent
= p
->wIndent
* 5 * tm
.tmAveCharWidth
;
773 space
.cx
= rect
.left
+ indent
- 2 * tm
.tmAveCharWidth
;
779 space
.cx
= rect
.left
+ indent
;
780 space
.cy
+= (p
->wVSpace
- 1) * tm
.tmHeight
;
785 space
.cx
+= p
->wHSpace
* 2 * tm
.tmAveCharWidth
;
790 INT free_width
= rect
.right
- (part
? (*line
)->rect
.right
: rect
.left
) - space
.cx
;
791 UINT low
= 0, curr
= len
, high
= len
, textlen
= 0;
797 GetTextExtentPoint(hDc
, text
, curr
, &textsize
);
799 if (textsize
.cx
<= free_width
) low
= curr
;
802 if (high
<= low
+ 1) break;
804 if (textsize
.cx
) curr
= (curr
* free_width
) / textsize
.cx
;
805 if (curr
<= low
) curr
= low
+ 1;
806 else if (curr
>= high
) curr
= high
- 1;
809 while (textlen
&& text
[textlen
] && text
[textlen
] != ' ') textlen
--;
811 if (!part
&& !textlen
) textlen
= MAX(low
, 1);
813 if (free_width
<= 0 || !textlen
)
816 space
.cx
= rect
.left
+ indent
;
817 space
.cx
= MIN(space
.cx
, rect
.right
- rect
.left
- 1);
821 if (!WINHELP_AppendText(&line
, &part
, &space
, &textsize
,
822 &line_ascent
, tm
.tmAscent
,
823 text
, textlen
, hFont
, color
, p
->link
) ||
824 (!newsize
&& (*line
)->rect
.bottom
> rect
.bottom
))
826 ReleaseDC(hWnd
, hDc
);
831 newsize
->cx
= MAX(newsize
->cx
, (*line
)->rect
.right
+ INTERNAL_BORDER_WIDTH
);
835 if (text
[0] == ' ') text
++, len
--;
840 newsize
->cy
= (*line
)->rect
.bottom
+ INTERNAL_BORDER_WIDTH
;
842 ReleaseDC(hWnd
, hDc
);
846 /***********************************************************************
851 static BOOL
WINHELP_AppendText(WINHELP_LINE
***linep
, WINHELP_LINE_PART
***partp
,
852 LPSIZE space
, LPSIZE textsize
,
853 INT
*line_ascent
, INT ascent
,
854 LPCSTR text
, UINT textlen
,
855 HFONT font
, COLORREF color
, HLPFILE_LINK
*link
)
859 WINHELP_LINE_PART
*part
;
862 if (!*partp
) /* New line */
864 *line_ascent
= ascent
;
866 handle
= GlobalAlloc(GMEM_FIXED
, sizeof(WINHELP_LINE
) + textlen
+
867 (link
? lstrlen(link
->lpszPath
) + 1 : 0));
868 if (!handle
) return FALSE
;
869 line
= GlobalLock(handle
);
871 part
= &line
->first_part
;
872 ptr
= GlobalLock(handle
);
873 ptr
+= sizeof(WINHELP_LINE
);
875 line
->rect
.top
= (**linep
? (**linep
)->rect
.bottom
: 0) + space
->cy
;
876 line
->rect
.bottom
= line
->rect
.top
;
877 line
->rect
.left
= space
->cx
;
878 line
->rect
.right
= space
->cx
;
880 if (**linep
) *linep
= &(**linep
)->next
;
888 if (*line_ascent
< ascent
)
890 WINHELP_LINE_PART
*p
;
891 for (p
= &line
->first_part
; p
; p
= p
->next
)
893 p
->rect
.top
+= ascent
- *line_ascent
;
894 p
->rect
.bottom
+= ascent
- *line_ascent
;
896 line
->rect
.bottom
+= ascent
- *line_ascent
;
897 *line_ascent
= ascent
;
900 handle
= GlobalAlloc(GMEM_FIXED
, sizeof(WINHELP_LINE_PART
) + textlen
+
901 (link
? lstrlen(link
->lpszPath
) + 1 : 0));
902 if (!handle
) return FALSE
;
903 part
= GlobalLock(handle
);
905 ptr
= GlobalLock(handle
);
906 ptr
+= sizeof(WINHELP_LINE_PART
);
909 hmemcpy(ptr
, text
, textlen
);
910 part
->rect
.left
= line
->rect
.right
+ (*partp
? space
->cx
: 0);
911 part
->rect
.right
= part
->rect
.left
+ textsize
->cx
;
912 line
->rect
.right
= part
->rect
.right
;
914 ((*partp
) ? line
->rect
.top
: line
->rect
.bottom
) + *line_ascent
- ascent
;
915 part
->rect
.bottom
= part
->rect
.top
+ textsize
->cy
;
916 line
->rect
.bottom
= MAX(line
->rect
.bottom
, part
->rect
.bottom
);
917 part
->hSelf
= handle
;
919 part
->wTextLen
= textlen
;
924 strcpy(ptr
+ textlen
, link
->lpszPath
);
925 part
->link
.lpszPath
= ptr
+ textlen
;
926 part
->link
.lHash
= link
->lHash
;
927 part
->link
.bPopup
= link
->bPopup
;
929 else part
->link
.lpszPath
= 0;
932 *partp
= &part
->next
;
939 /***********************************************************************
944 static VOID
WINHELP_CheckPopup(UINT msg
)
946 if (!Globals
.hPopupWnd
) return;
954 case WM_NCLBUTTONDOWN
:
955 case WM_NCMBUTTONDOWN
:
956 case WM_NCRBUTTONDOWN
:
957 DestroyWindow(Globals
.hPopupWnd
);
958 Globals
.hPopupWnd
= 0;
962 /***********************************************************************
964 * WINHELP_DeleteLines
967 static VOID
WINHELP_DeleteLines(WINHELP_WINDOW
*win
)
969 WINHELP_LINE
*line
, *next_line
;
970 WINHELP_LINE_PART
*part
, *next_part
;
971 for(line
= win
->first_line
; line
; line
= next_line
)
973 next_line
= line
->next
;
974 for(part
= &line
->first_part
; part
; part
= next_part
)
976 next_part
= part
->next
;
977 GlobalFree(part
->hSelf
);
983 /***********************************************************************
985 * WINHELP_DeleteWindow
988 static VOID
WINHELP_DeleteWindow(WINHELP_WINDOW
*win
)
992 for (w
= &Globals
.win_list
; *w
; w
= &(*w
)->next
)
999 if (win
->hShadowWnd
) DestroyWindow(win
->hShadowWnd
);
1000 HLPFILE_FreeHlpFilePage(win
->page
);
1001 WINHELP_DeleteLines(win
);
1002 GlobalFree(win
->hSelf
);
1005 /***********************************************************************
1010 static VOID
WINHELP_InitFonts(HWND hWnd
)
1012 WINHELP_WINDOW
*win
= (WINHELP_WINDOW
*) GetWindowLong(hWnd
, 0);
1013 LOGFONT logfontlist
[] = {
1014 {-10, 0, 0, 0, 400, 0, 0, 0, 0, 0, 0, 0, 32, "Helv"},
1015 {-12, 0, 0, 0, 700, 0, 0, 0, 0, 0, 0, 0, 32, "Helv"},
1016 {-12, 0, 0, 0, 700, 0, 0, 0, 0, 0, 0, 0, 32, "Helv"},
1017 {-12, 0, 0, 0, 400, 0, 0, 0, 0, 0, 0, 0, 32, "Helv"},
1018 {-12, 0, 0, 0, 700, 0, 0, 0, 0, 0, 0, 0, 32, "Helv"},
1019 {-10, 0, 0, 0, 700, 0, 0, 0, 0, 0, 0, 0, 32, "Helv"},
1020 { -8, 0, 0, 0, 400, 0, 0, 0, 0, 0, 0, 0, 32, "Helv"}};
1021 #define FONTS_LEN (sizeof(logfontlist)/sizeof(*logfontlist))
1023 static HFONT fonts
[FONTS_LEN
][2];
1024 static BOOL init
= 0;
1026 win
->fonts_len
= FONTS_LEN
;
1033 for(i
= 0; i
< FONTS_LEN
; i
++)
1035 LOGFONT logfont
= logfontlist
[i
];
1037 fonts
[i
][0] = CreateFontIndirect(&logfont
);
1038 logfont
.lfUnderline
= 1;
1039 fonts
[i
][1] = CreateFontIndirect(&logfont
);
1046 /***********************************************************************
1048 * WINHELP_MessageBoxIDS
1051 INT
WINHELP_MessageBoxIDS(UINT ids_text
, UINT ids_title
, WORD type
)
1053 CHAR text
[MAX_STRING_LEN
];
1054 CHAR title
[MAX_STRING_LEN
];
1056 LoadString(Globals
.hInstance
, ids_text
, text
, sizeof(text
));
1057 LoadString(Globals
.hInstance
, ids_title
, title
, sizeof(title
));
1059 return(MessageBox(0, text
, title
, type
));
1062 /***********************************************************************
1064 * MAIN_MessageBoxIDS_s
1067 INT
WINHELP_MessageBoxIDS_s(UINT ids_text
, LPCSTR str
, UINT ids_title
, WORD type
)
1069 CHAR text
[MAX_STRING_LEN
];
1070 CHAR title
[MAX_STRING_LEN
];
1071 CHAR newtext
[MAX_STRING_LEN
+ MAX_PATHNAME_LEN
];
1073 LoadString(Globals
.hInstance
, ids_text
, text
, sizeof(text
));
1074 LoadString(Globals
.hInstance
, ids_title
, title
, sizeof(title
));
1075 wsprintf(newtext
, text
, str
);
1077 return(MessageBox(0, newtext
, title
, type
));
1080 /* Local Variables: */
1081 /* c-file-style: "GNU" */