Module: wine Branch: master Commit: 82ffc04ef3b98c0cdc70b0c4ad373dd569c4c082 URL: http://source.winehq.org/git/wine.git/?a=commit;h=82ffc04ef3b98c0cdc70b0c4ad...
Author: Eric Pouech eric.pouech@orange.fr Date: Sat May 30 14:27:04 2009 +0200
winhlp32: Now manage windows with refcounts.
---
programs/winhlp32/macro.c | 6 ++-- programs/winhlp32/macro.lex.l | 3 +- programs/winhlp32/winhelp.c | 67 +++++++++++++++++++++++++++++++---------- programs/winhlp32/winhelp.h | 3 ++ 4 files changed, 59 insertions(+), 20 deletions(-)
diff --git a/programs/winhlp32/macro.c b/programs/winhlp32/macro.c index 3383545..c2fc3cc 100644 --- a/programs/winhlp32/macro.c +++ b/programs/winhlp32/macro.c @@ -281,7 +281,7 @@ static void CALLBACK MACRO_CloseSecondarys(void) WINE_TRACE("()\n"); for (win = Globals.win_list; win; win = win->next) if (lstrcmpi(win->info->name, "main")) - DestroyWindow(win->hMainWnd); + WINHELP_ReleaseWindow(win); }
static void CALLBACK MACRO_CloseWindow(LPCSTR lpszWindow) @@ -294,7 +294,7 @@ static void CALLBACK MACRO_CloseWindow(LPCSTR lpszWindow)
for (win = Globals.win_list; win; win = win->next) if (!lstrcmpi(win->info->name, lpszWindow)) - DestroyWindow(win->hMainWnd); + WINHELP_ReleaseWindow(win); }
static void CALLBACK MACRO_Compare(LPCSTR str) @@ -367,7 +367,7 @@ void CALLBACK MACRO_Exit(void) WINE_TRACE("()\n");
while (Globals.win_list) - DestroyWindow(Globals.win_list->hMainWnd); + WINHELP_ReleaseWindow(Globals.win_list); }
static void CALLBACK MACRO_ExtAbleItem(LPCSTR str, LONG u) diff --git a/programs/winhlp32/macro.lex.l b/programs/winhlp32/macro.lex.l index bf65fa0..67926cb 100644 --- a/programs/winhlp32/macro.lex.l +++ b/programs/winhlp32/macro.lex.l @@ -285,7 +285,7 @@ BOOL MACRO_ExecuteMacro(WINHELP_WINDOW* window, LPCSTR macro)
memset(lex_data, 0, sizeof(*lex_data)); lex_data->macroptr = macro; - lex_data->window = window; + lex_data->window = WINHELP_GrabWindow(window);
while ((t = yylex()) != EMPTY) { @@ -316,6 +316,7 @@ done: for (t = 0; t < lex_data->cache_used; t++) HeapFree(GetProcessHeap(), 0, lex_data->cache_string[t]); lex_data = prev_lex_data; + WINHELP_ReleaseWindow(window);
return ret; } diff --git a/programs/winhlp32/winhelp.c b/programs/winhlp32/winhelp.c index 8e6ba50..027bf65 100644 --- a/programs/winhlp32/winhelp.c +++ b/programs/winhlp32/winhelp.c @@ -500,11 +500,39 @@ static void WINHELP_DeletePageLinks(HLPFILE_PAGE* page)
/*********************************************************************** * + * WINHELP_GrabWindow + */ +WINHELP_WINDOW* WINHELP_GrabWindow(WINHELP_WINDOW* win) +{ + WINE_TRACE("Grab %p#%d++\n", win, win->ref_count); + win->ref_count++; + return win; +} + +/*********************************************************************** + * + * WINHELP_RelaseWindow + */ +BOOL WINHELP_ReleaseWindow(WINHELP_WINDOW* win) +{ + WINE_TRACE("Release %p#%d--\n", win, win->ref_count); + + if (!--win->ref_count) + { + DestroyWindow(win->hMainWnd); + return FALSE; + } + return TRUE; +} + +/*********************************************************************** + * * WINHELP_DeleteWindow */ static void WINHELP_DeleteWindow(WINHELP_WINDOW* win) { WINHELP_WINDOW** w; + BOOL bExit;
for (w = &Globals.win_list; *w; w = &(*w)->next) { @@ -514,6 +542,7 @@ static void WINHELP_DeleteWindow(WINHELP_WINDOW* win) break; } } + bExit = (Globals.wVersion >= 4 && !lstrcmpi(win->info->name, "main"));
if (Globals.active_win == win) { @@ -537,6 +566,10 @@ static void WINHELP_DeleteWindow(WINHELP_WINDOW* win)
if (win->page) HLPFILE_FreeHlpFile(win->page->file); HeapFree(GetProcessHeap(), 0, win); + + if (bExit) MACRO_Exit(); + if (!Globals.win_list) + PostQuitMessage(0); }
static char* WINHELP_GetCaption(WINHELP_WNDPAGE* wpage) @@ -706,9 +739,11 @@ BOOL WINHELP_CreateHelpWindow(WINHELP_WNDPAGE* wpage, int nCmdShow, BOOL remembe win->hHandCur = LoadCursorW(0, (LPWSTR)IDC_HAND); win->back.index = 0; win->font_scale = 1; + WINHELP_GrabWindow(win); } win->page = wpage->page; win->info = wpage->wininfo; + WINHELP_GrabWindow(win);
if (!bPopup && wpage->page && remember) { @@ -772,6 +807,14 @@ BOOL WINHELP_CreateHelpWindow(WINHELP_WNDPAGE* wpage, int nCmdShow, BOOL remembe for (macro = wpage->page->first_macro; macro; macro = macro->next) MACRO_ExecuteMacro(win, macro->lpszMacro); } + /* See #17681, in some cases, the newly created window is closed by the macros it contains + * (braindead), so deal with this case + */ + for (win = Globals.win_list; win; win = win->next) + { + if (!lstrcmpi(win->info->name, wpage->wininfo->name)) break; + } + if (!win || !WINHELP_ReleaseWindow(win)) return TRUE;
if (bPopup) { @@ -883,7 +926,7 @@ static BOOL WINHELP_HandleTextMouse(WINHELP_WINDOW* win, UINT msg, LPARAM lParam */ static BOOL WINHELP_CheckPopup(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, LRESULT* lret) { - HWND hPopup; + WINHELP_WINDOW* popup;
if (!Globals.active_popup) return FALSE;
@@ -916,9 +959,9 @@ static BOOL WINHELP_CheckPopup(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam case WM_NCLBUTTONDOWN: case WM_NCMBUTTONDOWN: case WM_NCRBUTTONDOWN: - hPopup = Globals.active_popup->hMainWnd; + popup = Globals.active_popup; Globals.active_popup = NULL; - DestroyWindow(hPopup); + WINHELP_ReleaseWindow(popup); return TRUE; } return FALSE; @@ -1422,7 +1465,8 @@ static LRESULT CALLBACK WINHELP_MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, switch (msgf->msg) { case WM_KEYUP: - if (msgf->wParam == VK_ESCAPE) DestroyWindow(hWnd); + if (msgf->wParam == VK_ESCAPE) + WINHELP_ReleaseWindow((WINHELP_WINDOW*)GetWindowLongPtr(hWnd, 0)); break; case WM_RBUTTONDOWN: { @@ -1486,18 +1530,9 @@ static LRESULT CALLBACK WINHELP_MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, CheckMenuItem((HMENU)wParam, MNID_OPTS_FONTS_LARGE, MF_BYCOMMAND | (win->font_scale == 2) ? MF_CHECKED : 0); break; - - case WM_NCDESTROY: - { - BOOL bExit; - win = (WINHELP_WINDOW*) GetWindowLongPtr(hWnd, 0); - bExit = (Globals.wVersion >= 4 && !lstrcmpi(win->info->name, "main")); - WINHELP_DeleteWindow(win); - - if (bExit) MACRO_Exit(); - if (!Globals.win_list) - PostQuitMessage(0); - } + case WM_DESTROY: + win = (WINHELP_WINDOW*) GetWindowLongPtr(hWnd, 0); + WINHELP_DeleteWindow(win); break; } return DefWindowProc(hWnd, msg, wParam, lParam); diff --git a/programs/winhlp32/winhelp.h b/programs/winhlp32/winhelp.h index 70e2dc2..e770cb5 100644 --- a/programs/winhlp32/winhelp.h +++ b/programs/winhlp32/winhelp.h @@ -71,6 +71,7 @@ typedef struct tagPageSet
typedef struct tagWinHelp { + unsigned ref_count; WINHELP_BUTTON* first_button; HLPFILE_PAGE* page;
@@ -151,6 +152,8 @@ void WINHELP_DeleteBackSet(WINHELP_WINDOW*); HLPFILE* WINHELP_LookupHelpFile(LPCSTR lpszFile); HLPFILE_WINDOWINFO* WINHELP_GetWindowInfo(HLPFILE* hlpfile, LPCSTR name); void WINHELP_LayoutMainWindow(WINHELP_WINDOW* win); +WINHELP_WINDOW* WINHELP_GrabWindow(WINHELP_WINDOW*); +BOOL WINHELP_ReleaseWindow(WINHELP_WINDOW*);
extern const char MAIN_WIN_CLASS_NAME[]; extern const char BUTTON_BOX_WIN_CLASS_NAME[];