winhlp32: Now manage windows with refcounts.

This commit is contained in:
Eric Pouech 2009-05-30 14:27:04 +02:00 committed by Alexandre Julliard
parent e3beef0af5
commit 82ffc04ef3
4 changed files with 59 additions and 20 deletions

View file

@ -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)

View file

@ -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;
}

View file

@ -498,6 +498,33 @@ 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
@ -505,6 +532,7 @@ static void WINHELP_DeletePageLinks(HLPFILE_PAGE* page)
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);

View file

@ -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[];