[PATCH 18/45] [WinHelp]: set back a decent popup size computation

Eric Pouech eric.pouech at orange.fr
Sun Mar 23 04:19:07 CDT 2008




A+
---

 programs/winhelp/winhelp.c |  172 ++++++++++++++++++++++++++++++++------------
 programs/winhelp/winhelp.h |    2 -
 2 files changed, 125 insertions(+), 49 deletions(-)


diff --git a/programs/winhelp/winhelp.c b/programs/winhelp/winhelp.c
index 055564d..2ec0313 100644
--- a/programs/winhelp/winhelp.c
+++ b/programs/winhelp/winhelp.c
@@ -47,12 +47,12 @@ static LRESULT CALLBACK WINHELP_ButtonBoxWndProc(HWND, UINT, WPARAM, LPARAM);
 static LRESULT CALLBACK WINHELP_ButtonWndProc(HWND, UINT, WPARAM, LPARAM);
 static LRESULT CALLBACK WINHELP_HistoryWndProc(HWND, UINT, WPARAM, LPARAM);
 static LRESULT CALLBACK WINHELP_ShadowWndProc(HWND, UINT, WPARAM, LPARAM);
-static void    WINHELP_CheckPopup(UINT);
+static BOOL    WINHELP_CheckPopup(HWND, UINT, WPARAM, LPARAM, LRESULT*);
 static void    WINHELP_DeleteWindow(WINHELP_WINDOW*);
 static void    WINHELP_DeletePageLinks(WINHELP_WINDOW* win);
 static void    WINHELP_FillRichEdit(HWND hText, WINHELP_WINDOW *win);
 
-WINHELP_GLOBALS Globals = {3, NULL, NULL, TRUE, NULL, NULL, NULL, NULL};
+WINHELP_GLOBALS Globals = {3, NULL, TRUE, NULL, NULL, NULL, NULL, NULL};
 
 #define CTL_ID_BUTTON   0x700
 #define CTL_ID_TEXT     0x701
@@ -194,29 +194,30 @@ HLPFILE_WINDOWINFO*     WINHELP_GetWindowInfo(HLPFILE* hlpfile, LPCSTR name)
  *
  */
 static HLPFILE_WINDOWINFO*     WINHELP_GetPopupWindowInfo(HLPFILE* hlpfile,
-                                                          HWND hParentWnd,
+                                                          WINHELP_WINDOW* parent,
                                                           LPARAM mouse)
 {
     static      HLPFILE_WINDOWINFO      wi;
-    RECT parent_rect;
+    RECT                parent_rect;
 
     wi.type[0] = wi.name[0] = wi.caption[0] = '\0';
 
     /* Calculate horizontal size and position of a popup window */
-    GetWindowRect(hParentWnd, &parent_rect);
+    GetWindowRect(parent->hMainWnd, &parent_rect);
     wi.size.cx = (parent_rect.right  - parent_rect.left) / 2;
     wi.size.cy = 10; /* need a non null value, so that border are taken into account while computing */
 
     wi.origin.x = (short)LOWORD(mouse);
     wi.origin.y = (short)HIWORD(mouse);
-    ClientToScreen(hParentWnd, &wi.origin);
+    ClientToScreen(parent->hMainWnd, &wi.origin);
     wi.origin.x -= wi.size.cx / 2;
     wi.origin.x  = min(wi.origin.x, GetSystemMetrics(SM_CXSCREEN) - wi.size.cx);
     wi.origin.x  = max(wi.origin.x, 0);
 
     wi.style = SW_SHOW;
     wi.win_style = WS_POPUP | WS_BORDER;
-    wi.sr_color = wi.sr_color = 0xFFFFFF;
+    wi.sr_color = parent->info->sr_color;
+    wi.nsr_color = 0xFFFFFF;
 
     return &wi;
 }
@@ -452,7 +453,7 @@ static LRESULT  WINHELP_HandleCommand(HWND hSrcWnd, LPARAM lParam)
 void            WINHELP_LayoutMainWindow(WINHELP_WINDOW* win)
 {
     RECT        rect, button_box_rect;
-    INT         text_top;
+    INT         text_top = 0;
     HWND        hButtonBoxWnd = GetDlgItem(win->hMainWnd, CTL_ID_BUTTON);
     HWND        hTextWnd = GetDlgItem(win->hMainWnd, CTL_ID_TEXT);
 
@@ -464,8 +465,8 @@ void            WINHELP_LayoutMainWindow(WINHELP_WINDOW* win)
                  rect.right - rect.left,
                  rect.bottom - rect.top, 0);
 
-    GetWindowRect(hButtonBoxWnd, &button_box_rect);
-    text_top = rect.top + button_box_rect.bottom - button_box_rect.top;
+    if (GetWindowRect(hButtonBoxWnd, &button_box_rect))
+        text_top = rect.top + button_box_rect.bottom - button_box_rect.top;
 
     SetWindowPos(hTextWnd, HWND_TOP,
                  rect.left, text_top,
@@ -569,11 +570,10 @@ BOOL WINHELP_CreateHelpWindow(HLPFILE_PAGE* page, HLPFILE_WINDOWINFO* wi,
                               int nCmdShow)
 {
     WINHELP_WINDOW *win, *oldwin;
-    HWND hWnd, hTextWnd;
+    HWND hTextWnd;
     BOOL bPrimary;
     BOOL bPopup;
     LPSTR name;
-    DWORD ex_style;
 
     bPrimary = !lstrcmpi(wi->name, "main");
     bPopup = !bPrimary && (wi->win_style & WS_POPUP);
@@ -597,7 +597,10 @@ BOOL WINHELP_CreateHelpWindow(HLPFILE_PAGE* page, HLPFILE_WINDOWINFO* wi,
     win->info = wi;
     win->page_links = NULL;
 
-    Globals.active_win = win;
+    if (bPopup)
+        Globals.active_popup = win;
+    else
+        Globals.active_win = win;
 
     /* Initialize default pushbuttons */
     if (bPrimary && page)
@@ -617,7 +620,7 @@ BOOL WINHELP_CreateHelpWindow(HLPFILE_PAGE* page, HLPFILE_WINDOWINFO* wi,
     }
 
     /* Initialize file specific pushbuttons */
-    if (!(wi->win_style & WS_POPUP) && page)
+    if (!bPopup && page)
     {
         HLPFILE_MACRO  *macro;
         for (macro = page->file->first_macro; macro; macro = macro->next)
@@ -646,31 +649,54 @@ BOOL WINHELP_CreateHelpWindow(HLPFILE_PAGE* page, HLPFILE_WINDOWINFO* wi,
         }
     }
 
-    ex_style = 0;
-    if (bPopup) ex_style = WS_EX_TOOLWINDOW;
-    hWnd = CreateWindowEx(ex_style, MAIN_WIN_CLASS_NAME,
-                        wi->caption,
-                        bPrimary ? WS_OVERLAPPEDWINDOW : wi->win_style,
-                        wi->origin.x, wi->origin.y, wi->size.cx, wi->size.cy,
-                        NULL, bPrimary ? LoadMenu(Globals.hInstance, MAKEINTRESOURCE(MAIN_MENU)) : 0,
-                        Globals.hInstance, win);
-    /* Create button box and text Window */
+    win->hMainWnd = CreateWindowEx((bPopup) ? WS_EX_TOOLWINDOW : 0, MAIN_WIN_CLASS_NAME,
+                                   wi->caption,
+                                   bPrimary ? WS_OVERLAPPEDWINDOW : wi->win_style,
+                                   wi->origin.x, wi->origin.y, wi->size.cx, wi->size.cy,
+                                   bPopup ? Globals.active_win->hMainWnd : NULL,
+                                   bPrimary ? LoadMenu(Globals.hInstance, MAKEINTRESOURCE(MAIN_MENU)) : 0,
+                                   Globals.hInstance, win);
     if (!bPopup)
+        /* Create button box and text Window */
         CreateWindow(BUTTON_BOX_WIN_CLASS_NAME, "", WS_CHILD | WS_VISIBLE,
-                     0, 0, 0, 0, hWnd, (HMENU)CTL_ID_BUTTON, Globals.hInstance, NULL);
+                     0, 0, 0, 0, win->hMainWnd, (HMENU)CTL_ID_BUTTON, Globals.hInstance, NULL);
 
     hTextWnd = CreateWindow(RICHEDIT_CLASS, NULL,
                             ES_MULTILINE | ES_READONLY | WS_CHILD | WS_HSCROLL | WS_VSCROLL | WS_VISIBLE,
-                            0, 0, 0, 0, hWnd, (HMENU)CTL_ID_TEXT, Globals.hInstance, NULL);
+                            0, 0, 0, 0, win->hMainWnd, (HMENU)CTL_ID_TEXT, Globals.hInstance, NULL);
+
     SendMessage(hTextWnd, EM_SETEVENTMASK, 0,
                 SendMessage(hTextWnd, EM_GETEVENTMASK, 0, 0) | ENM_MOUSEEVENTS);
 
-    WINHELP_LayoutMainWindow(win);
-    if (bPopup) Globals.hPopupWnd = hWnd;
+    if (bPopup)
+    {
+        HWND    hTextWnd = GetDlgItem(win->hMainWnd, CTL_ID_TEXT);
+        DWORD   mask = SendMessage(hTextWnd, EM_GETEVENTMASK, 0, 0);
+
+        WINHELP_FillRichEdit(hTextWnd, win);
+
+        /* we need the window to be shown for richedit to compute the size */
+        ShowWindow(win->hMainWnd, nCmdShow);
+        SendMessage(hTextWnd, EM_SETEVENTMASK, 0, mask | ENM_REQUESTRESIZE);
+        SendMessage(hTextWnd, EM_REQUESTRESIZE, 0, 0);
+        SendMessage(hTextWnd, EM_SETEVENTMASK, 0, mask);
+
+#if 0
+        win->hShadowWnd = CreateWindowEx(WS_EX_TOOLWINDOW, SHADOW_WIN_CLASS_NAME, "", WS_POPUP,
+                                         origin.x + SHADOW_DX, origin.y + SHADOW_DY,
+                                         new_window_size.cx, new_window_size.cy,
+                                         0, 0, Globals.hInstance, 0);
+        SetWindowPos(win->hShadowWnd, hWnd, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
+        ShowWindow(win->hShadowWnd, SW_NORMAL);
+#endif
+    }
+    else
+    {
+        WINHELP_LayoutMainWindow(win);
+        ShowWindow(win->hMainWnd, nCmdShow);
+    }
 
-    if (bPopup) WINHELP_FillRichEdit(hWnd, win);
-    ShowWindow(hWnd, nCmdShow);
-    UpdateWindow(hWnd);
+    UpdateWindow(win->hMainWnd);
 
     return TRUE;
 }
@@ -800,7 +826,7 @@ static BOOL WINHELP_HandleTextMouse(WINHELP_WINDOW* win, const MSGFILTER* msgf)
             case hlp_link_popup:
                 if ((hlpfile = WINHELP_LookupHelpFile(link->string)))
                     WINHELP_CreateHelpWindowByHash(hlpfile, link->hash,
-                                                   WINHELP_GetPopupWindowInfo(hlpfile, win->hMainWnd, msgf->lParam),
+                                                   WINHELP_GetPopupWindowInfo(hlpfile, win, msgf->lParam),
                                                    SW_NORMAL);
                 break;
             case hlp_link_macro:
@@ -825,23 +851,28 @@ static LRESULT CALLBACK WINHELP_MainWndProc(HWND hWnd, UINT msg, WPARAM wParam,
 {
     WINHELP_WINDOW *win;
     WINHELP_BUTTON *button;
+    LRESULT         ret;
 
-    WINHELP_CheckPopup(msg);
+    if (WINHELP_CheckPopup(hWnd, msg, wParam, lParam, &ret)) return ret;
 
     switch (msg)
     {
     case WM_NCCREATE:
         win = (WINHELP_WINDOW*) ((LPCREATESTRUCT) lParam)->lpCreateParams;
         SetWindowLong(hWnd, 0, (LONG) win);
-        win->hMainWnd = hWnd;
         break;
 
     case WM_WINDOWPOSCHANGED:
         WINHELP_LayoutMainWindow((WINHELP_WINDOW*) GetWindowLong(hWnd, 0));
         break;
 
+    case WM_ACTIVATE:
+        if (wParam != WA_INACTIVE && !(GetWindowLong(hWnd, GWL_STYLE) & WS_POPUP))
+            Globals.active_win = (WINHELP_WINDOW*)GetWindowLong(hWnd, 0);
+        break;
+
     case WM_COMMAND:
-        Globals.active_win = win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0);
+        win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0);
         switch (wParam)
 	{
             /* Menu FILE */
@@ -874,9 +905,9 @@ static LRESULT CALLBACK WINHELP_MainWndProc(HWND hWnd, UINT msg, WPARAM wParam,
             break;
 	}
         break;
-    case WM_DESTROY:
-        if (Globals.hPopupWnd) DestroyWindow(Globals.hPopupWnd);
-        break;
+/* EPP     case WM_DESTROY: */
+/* EPP         if (Globals.active_popup) DestroyWindow(Globals.active_popup->hMainWnd); */
+/* EPP         break; */
     case WM_COPYDATA:
         return WINHELP_HandleCommand((HWND)wParam, lParam);
     case WM_KEYDOWN:
@@ -889,8 +920,25 @@ static LRESULT CALLBACK WINHELP_MainWndProc(HWND hWnd, UINT msg, WPARAM wParam,
     case WM_NOTIFY:
         if (wParam == CTL_ID_TEXT)
         {
-            return WINHELP_HandleTextMouse((WINHELP_WINDOW*)GetWindowLong(hWnd, 0),
-                                           (const MSGFILTER*)lParam);
+            NMHDR*      nmhdr = (NMHDR*)lParam;
+            RECT        rc;
+
+            switch (nmhdr->code)
+            {
+            case EN_MSGFILTER:
+                return WINHELP_HandleTextMouse((WINHELP_WINDOW*)GetWindowLong(hWnd, 0),
+                                               (const MSGFILTER*)lParam);
+            case EN_REQUESTRESIZE:
+                rc = ((REQRESIZE*)lParam)->rc;
+                win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0);
+                AdjustWindowRect(&rc, GetWindowLong(win->hMainWnd, GWL_STYLE),
+                                 FALSE);
+                SetWindowPos(win->hMainWnd, HWND_TOP, 0, 0,
+                             rc.right - rc.left, rc.bottom - rc.top,
+                             SWP_NOMOVE | SWP_NOZORDER);
+                WINHELP_LayoutMainWindow(win);
+                break;
+            }
         }
         break;
 
@@ -900,8 +948,6 @@ static LRESULT CALLBACK WINHELP_MainWndProc(HWND hWnd, UINT msg, WPARAM wParam,
 
         win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0);
 
-        if (hWnd == Globals.hPopupWnd) Globals.hPopupWnd = 0;
-
         bExit = (Globals.wVersion >= 4 && !lstrcmpi(win->lpszName, "main"));
 
         WINHELP_DeleteWindow(win);
@@ -972,7 +1018,7 @@ static LRESULT CALLBACK WINHELP_ButtonBoxWndProc(HWND hWnd, UINT msg, WPARAM wPa
     SIZE button_size;
     INT  x, y;
 
-    WINHELP_CheckPopup(msg);
+    if (WINHELP_CheckPopup(hWnd, msg, wParam, lParam, NULL)) return 0L;
 
     switch (msg)
     {
@@ -1049,6 +1095,8 @@ static LRESULT CALLBACK WINHELP_ButtonBoxWndProc(HWND hWnd, UINT msg, WPARAM wPa
  */
 static LRESULT CALLBACK WINHELP_ButtonWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
 {
+    WINHELP_CheckPopup(hWnd, msg, wParam, lParam, NULL);
+
     if (msg == WM_KEYDOWN)
     {
         switch (wParam)
@@ -1137,7 +1185,6 @@ static LRESULT CALLBACK WINHELP_HistoryWndProc(HWND hWnd, UINT msg, WPARAM wPara
  */
 static LRESULT CALLBACK WINHELP_ShadowWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
 {
-    WINHELP_CheckPopup(msg);
     return DefWindowProc(hWnd, msg, wParam, lParam);
 }
 
@@ -1145,22 +1192,49 @@ static LRESULT CALLBACK WINHELP_ShadowWndProc(HWND hWnd, UINT msg, WPARAM wParam
  *
  *           WINHELP_CheckPopup
  */
-static void WINHELP_CheckPopup(UINT msg)
+static BOOL WINHELP_CheckPopup(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, LRESULT* lret)
 {
-    if (!Globals.hPopupWnd) return;
+    HWND        popup;
+
+    if (!Globals.active_popup) return FALSE;
 
+    if (lret) *lret = 0L;
     switch (msg)
     {
-    case WM_COMMAND:
+    /* case WM_COMMAND: */
+    case WM_NOTIFY:
+        {
+            MSGFILTER*  msgf = (MSGFILTER*)lParam;
+            if (msgf->nmhdr.code == EN_MSGFILTER)
+            {
+                if (!WINHELP_CheckPopup(hWnd, msgf->msg, msgf->wParam, msgf->lParam, NULL))
+                    return FALSE;
+                if (lret) *lret = 1;
+                return TRUE;
+            }
+        }
+        break;
+    case WM_ACTIVATE:
+        if (wParam != WA_INACTIVE || (HWND)lParam == Globals.active_win->hMainWnd || (HWND)lParam == Globals.active_popup->hMainWnd)
+            break;
     case WM_LBUTTONDOWN:
     case WM_MBUTTONDOWN:
     case WM_RBUTTONDOWN:
     case WM_NCLBUTTONDOWN:
     case WM_NCMBUTTONDOWN:
     case WM_NCRBUTTONDOWN:
-        DestroyWindow(Globals.hPopupWnd);
-        Globals.hPopupWnd = 0;
+    case WM_LBUTTONUP:
+    case WM_MBUTTONUP:
+    case WM_RBUTTONUP:
+    case WM_NCLBUTTONUP:
+    case WM_NCMBUTTONUP:
+    case WM_NCRBUTTONUP:
+        popup = Globals.active_popup->hMainWnd;
+        Globals.active_popup = NULL;
+        DestroyWindow(popup);
+        return TRUE;
     }
+    return FALSE;
 }
 
 /******************************************************************
@@ -1205,6 +1279,8 @@ static void WINHELP_DeleteWindow(WINHELP_WINDOW* win)
         if (Globals.win_list)
             SetActiveWindow(Globals.win_list->hMainWnd);
     }
+    if (win == Globals.active_popup)
+        Globals.active_popup = NULL;
 
     for (b = win->first_button; b; b = bp)
     {
diff --git a/programs/winhelp/winhelp.h b/programs/winhelp/winhelp.h
index 58c4df8..4d09ae2 100644
--- a/programs/winhelp/winhelp.h
+++ b/programs/winhelp/winhelp.h
@@ -115,9 +115,9 @@ typedef struct
 {
     UINT                wVersion;
     HANDLE              hInstance;
-    HWND                hPopupWnd;
     BOOL                isBook;
     WINHELP_WINDOW*     active_win;
+    WINHELP_WINDOW*     active_popup;
     WINHELP_WINDOW*     win_list;
     WNDPROC             button_proc;
     WINHELP_DLL*        dlls;





More information about the wine-patches mailing list