private void ResizeCustomControl(IntPtr hWnd)
        {
            if (hWnd == m_hWnd)
            {
                IntPtr hSelectButton =
                    InteropUtil.AssumeNonZero(InteropUtil.GetDlgItem(InteropUtil.AssumeNonZero(hWnd),
                                                                     InteropUtil.ID_SELECT));
                IntPtr hOkButton =
                    InteropUtil.AssumeNonZero(InteropUtil.GetDlgItem(InteropUtil.AssumeNonZero(hWnd),
                                                                     InteropUtil.ID_CUSTOM_CANCEL));

                IntPtr hParent  = InteropUtil.AssumeNonZero(InteropUtil.GetParent(hWnd));
                IntPtr fileName =
                    InteropUtil.AssumeNonZero(InteropUtil.GetDlgItem(hParent, InteropUtil.ID_FileNameCombo));

                /*var right = fileName.GetWindowPlacement().Right;
                 * var top = hSelectButton.GetWindowPlacement().Top;*/

                var rect = new InteropUtil.RECT();
                InteropUtil.WINDOWPLACEMENT selectRect = InteropUtil.GetWindowPlacement(hSelectButton);

                rect.top    = selectRect.Top;
                rect.bottom = selectRect.Bottom;
                rect.right  = InteropUtil.GetWindowPlacement(fileName).Right;
                rect.left   = rect.right - (m_cancelWidth + m_buttonGap + m_selectWidth);

                ResizeCustomControl(hWnd, rect, hOkButton, hSelectButton);
            }
        }
        private void ResizeCustomControl(IntPtr hWnd, InteropUtil.RECT rect, params IntPtr[] buttons)
        {
            InteropUtil.Assume(buttons != null && buttons.Length > 0);

            InteropUtil.AssumeNonZero(hWnd);

            InteropUtil.WINDOWPLACEMENT wndLoc = InteropUtil.GetWindowPlacement(hWnd);

            wndLoc.Right = rect.right;
            InteropUtil.SetWindowPlacement(hWnd, ref wndLoc);

            foreach (IntPtr hBtn in buttons)
            {
                int btnRight, btnWidth;

                m_calcPosMap[InteropUtil.GetDlgCtrlID(hBtn)](this, rect.right, out btnRight, out btnWidth);

                PositionButton(hBtn, btnRight, btnWidth);
            }

            //see bug # 844
            //We clip hWnd to only draw in the rectangle around our custom buttons.
            //When we supply a custom dialog template to GetOpenFileName(), it adds
            //an extra HWND to the open file dialog, and then sticks all the controls
            //in the dialog //template inside the HWND. It then resizes the control
            //to stretch from the top of the open file dialog to the bottom of the
            //window, extending the bottom of the window large enough to include the
            //additional height of the dialog template. This ends up sticking our custom
            //buttons at the bottom of the window, which is what we want.
            //
            //However, the fact that the parent window extends from the top of the open
            //file dialog was causing some painting problems on Windows XP SP 3 systems.
            //Basically, because the window was covering the predefined controls on the
            //open file dialog, they were not getting painted. This results in a blank
            //window. I tried setting an extended WS_EX_TRANSPARENT style on the dialog,
            //but that didn't help.
            //
            //So, to fix the problem I setup a window region for the synthetic HWND.
            //This clips the drawing of the window to only within the region containing
            //the custom buttons, and thus avoids the problem.
            //
            //I'm not sure why this wasn't an issue on Vista.
            IntPtr hRgn = InteropUtil.CreateRectRgnIndirect(ref rect);

            try
            {
                if (InteropUtil.SetWindowRgn(hWnd, hRgn, true) == 0)
                {
                    //setting the region failed, so we need to delete the region we created above.
                    InteropUtil.DeleteObject(hRgn);
                }
            }
            catch
            {
                if (hRgn != IntPtr.Zero)
                {
                    InteropUtil.DeleteObject(hRgn);
                }
            }
        }
        private void PositionButton(IntPtr hWnd, int right, int width)
        {
            InteropUtil.AssumeNonZero(hWnd);
            int id = InteropUtil.GetDlgCtrlID(hWnd);

            //hWnd.BringWindowToTop();

            InteropUtil.WINDOWPLACEMENT buttonLoc = InteropUtil.GetWindowPlacement(hWnd);

            buttonLoc.Right = right;
            buttonLoc.Left  = buttonLoc.Right - width;
            InteropUtil.SetWindowPlacement(hWnd, ref buttonLoc);
            InteropUtil.InvalidateRect(hWnd, IntPtr.Zero, true);
        }
        private void InitDialog(IntPtr hWnd)
        {
            m_hWnd = hWnd;

            IntPtr hParent = InteropUtil.AssumeNonZero(InteropUtil.GetParent(hWnd));

            InteropUtil.SetWindowSubclass(hParent, m_openFileSubClassDelegate, 0, 0);

            //disable and hide the filter combo box
            IntPtr hFilterCombo = InteropUtil.AssumeNonZero(InteropUtil.GetDlgItem(hParent, InteropUtil.ID_FilterCombo));

            InteropUtil.EnableWindow(hFilterCombo, false);
            InteropUtil.SendMessage(hParent, InteropUtil.CDM_HIDECONTROL, InteropUtil.ID_FilterCombo, 0);
            InteropUtil.SendMessage(hParent, InteropUtil.CDM_HIDECONTROL, InteropUtil.ID_FilterLabel, 0);

            //update the file name label
            IntPtr hFileNameLabel =
                InteropUtil.AssumeNonZero(InteropUtil.GetDlgItem(hParent, InteropUtil.ID_FileNameLabel));

            if (FileNameLabel != String.Empty)
            {
                InteropUtil.SendMessageString(hFileNameLabel, InteropUtil.WM_SETTEXT, 0, FileNameLabel);
            }

            //find the button controls in the parent
            IntPtr hOkButton     = InteropUtil.AssumeNonZero(InteropUtil.GetDlgItem(hParent, InteropUtil.IDOK));
            IntPtr hCancelButton = InteropUtil.AssumeNonZero(InteropUtil.GetDlgItem(hParent, InteropUtil.IDCANCEL));

            //We don't want the accelerator keys for the ok and cancel buttons to work, because
            //they are not shown on the dialog. However, we still want the buttons enabled
            //so that "esc" and "enter" have the behavior they used to. So, we just
            //clear out their text instead.
            InteropUtil.SetWindowTextW(hOkButton, String.Empty);
            InteropUtil.SetWindowTextW(hCancelButton, String.Empty);

            //find our button controls
            IntPtr hSelectButton       = InteropUtil.AssumeNonZero(InteropUtil.GetDlgItem(hWnd, InteropUtil.ID_SELECT));
            IntPtr hCustomCancelButton =
                InteropUtil.AssumeNonZero(InteropUtil.GetDlgItem(hWnd, InteropUtil.ID_CUSTOM_CANCEL));

            if (!String.IsNullOrEmpty(SelectLabel))
            {
                InteropUtil.SetWindowTextW(hSelectButton, SelectLabel);
            }
            if (!String.IsNullOrEmpty(CancelLabel))
            {
                InteropUtil.SetWindowTextW(hCustomCancelButton, CancelLabel);
            }

            //copy the font from the parent's buttons
            InteropUtil.LoadFontFrom(hSelectButton, hOkButton);
            InteropUtil.LoadFontFrom(hCustomCancelButton, hCancelButton);

            InteropUtil.WINDOWPLACEMENT cancelLoc = InteropUtil.GetWindowPlacement(hCancelButton);

            //hide the ok and cancel buttons
            InteropUtil.SendMessage(hParent, InteropUtil.CDM_HIDECONTROL, InteropUtil.IDOK, 0);
            InteropUtil.SendMessage(hParent, InteropUtil.CDM_HIDECONTROL, InteropUtil.IDCANCEL, 0);

            //expand the file name combo to take up the space left by the OK and cancel buttons.
            IntPtr hFileName = InteropUtil.AssumeNonZero(InteropUtil.GetDlgItem(hParent, InteropUtil.ID_FileNameCombo));

            InteropUtil.WINDOWPLACEMENT fileNameLoc = InteropUtil.GetWindowPlacement(hFileName);
            fileNameLoc.Right = InteropUtil.GetWindowPlacement(hOkButton).Right;
            InteropUtil.SetWindowPlacement(hFileName, ref fileNameLoc);

            InteropUtil.WINDOWPLACEMENT parentLoc = InteropUtil.GetWindowPlacement(hParent);

            //subtract the height of the missing cancel button
            parentLoc.Bottom -= (cancelLoc.Bottom - cancelLoc.Top);
            InteropUtil.SetWindowPlacement(hParent, ref parentLoc);

            //move the select and custom cancel buttons to the right hand side of the window:

            InteropUtil.WINDOWPLACEMENT selectLoc       = InteropUtil.GetWindowPlacement(hSelectButton);
            InteropUtil.WINDOWPLACEMENT customCancelLoc = InteropUtil.GetWindowPlacement(hCustomCancelButton);
            m_cancelWidth = customCancelLoc.Right - customCancelLoc.Left;
            m_selectWidth = selectLoc.Right - selectLoc.Left;
            m_buttonGap   = customCancelLoc.Left - selectLoc.Right;

            InteropUtil.WINDOWPLACEMENT ctrlLoc = InteropUtil.GetWindowPlacement(hWnd);
            ctrlLoc.Right = fileNameLoc.Right;

            //ResizeCustomControl(hWnd, fileNameLoc.Right, hCustomCancelButton, hSelectButton);
            ResizeCustomControl(hWnd);
        }