public static extern bool GetWindowInfo(IntPtr hWnd, ref WINDOWINFO pwi);
/// <summary> /// Initializes the IContentEditor. /// </summary> /// <param name="factory"></param> /// <param name="contentEditorSite"></param> /// <param name="internetSecurityManager"></param> /// <param name="wysiwygHTML"></param> /// <param name="previewHTML"></param> /// <param name="newEditingContext"></param> /// <param name="templateStrategy"></param> /// <param name="dlControlFlags"> /// For Mail, these flags should always include DLCTL_DLIMAGES | DLCTL_VIDEOS | DLCTL_BGSOUNDS so that local /// images, videos and sounds are loaded. To block external content, it should also include /// DLCTL_PRAGMA_NO_CACHE | DLCTL_FORCEOFFLINE | DLCTL_NO_CLIENTPULL so that external images are not loaded /// and are displayed as a red X instead. /// </param> /// <param name="color"></param> private void ContentEditorProxyCore(ContentEditorFactory factory, IContentEditorSite contentEditorSite, IInternetSecurityManager internetSecurityManager, string wysiwygHTML, string previewHTML, IBlogPostEditingContext newEditingContext, BlogPostHtmlEditorControl.TemplateStrategy templateStrategy, int dlControlFlags, string color) { try { Debug.Assert(contentEditorSite is IUIFramework, "IContentEditorSite must also implement IUIFramework"); Debug.Assert(contentEditorSite is IDropTarget, "IContentEditorSite must also implement IDropTarget"); ApplyInstalledCulture(); this.factory = factory; _wysiwygHTML = wysiwygHTML; _previewHTML = previewHTML; _contentEditorSite = contentEditorSite; IntPtr p = _contentEditorSite.GetWindowHandle(); WINDOWINFO info = new WINDOWINFO(); User32.GetWindowInfo(p, ref info); panel = new Panel(); panel.Top = 0; panel.Left = 0; panel.Width = Math.Max(info.rcWindow.Width, 200); panel.Height = Math.Max(info.rcWindow.Height, 200); panel.CreateControl(); User32.SetParent(panel.Handle, p); accountAdapter = new ContentEditorAccountAdapter(); mainFrame = new MainFrameWindowAdapter(p, panel, _contentEditorSite, accountAdapter.Id); context = newEditingContext; contentEditor = new ContentEditor(mainFrame, panel, mainFrame, internetSecurityManager, templateStrategy, dlControlFlags); // Prevents asserts contentEditor.DisableSpelling(); contentEditor.OnEditorAccountChanged(accountAdapter); contentEditor.DocumentComplete += new EventHandler(blogPostHtmlEditor_DocumentComplete); contentEditor.GotFocus += new EventHandler(contentEditor_GotFocus); contentEditor.LostFocus += new EventHandler(contentEditor_LostFocus); contentEditor.Initialize(context, accountAdapter, wysiwygHTML, previewHTML, false); if (!string.IsNullOrEmpty(color)) { contentEditor.IndentColor = color; } } catch (Exception ex) { // Something went wrong, make sure we don't reuse a cached editor HtmlEditorControl.DisposeCachedEditor(); Trace.Fail(ex.ToString()); Trace.Flush(); throw; } }
/// <summary> /// The hook procedure for window messages generated by the FileOpenDialog /// </summary> /// <param name="hWnd">the handle of the window at which this message is targeted</param> /// <param name="msg">the message identifier</param> /// <param name="wParam">message-specific parameter data</param> /// <param name="lParam">mess-specific parameter data</param> /// <returns></returns> public IntPtr MyHookProc(IntPtr hWnd, UInt32 msg, Int32 wParam, Int32 lParam) { try { if (hWnd == IntPtr.Zero) return IntPtr.Zero; switch (msg) { // We're not interested in every possible message; just return a NULL for those we don't care about default: { return IntPtr.Zero; } // WM_INITDIALOG - at this point the OpenFileDialog exists, so we pull the user-supplied control // into the FileOpenDialog now, using the SetParent API. case WM.INITDIALOG: { _hWndParent = User32.GetParent(hWnd); //setting a bool for whether the OS is RTL (not the installed language of WLW) IsRTL = (User32.GetWindowLong(_hWndParent, User32.GWL_EXSTYLE) & User32.WS_EX_LAYOUTRTL) > 0; //account for large title bar, borders for adjusting control locations TITLEBARINFO titleBarInfo = new TITLEBARINFO(); titleBarInfo.cbSize = (uint)Marshal.SizeOf(titleBarInfo); if (!User32.GetTitleBarInfo(_hWndParent, ref titleBarInfo)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } WINDOWINFO info = new WINDOWINFO(); info.cbSize = (uint)Marshal.SizeOf(info); if (!User32.GetWindowInfo(_hWndParent, ref info)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } _extraWindowHeight = (titleBarInfo.rcTitleBar.bottom - titleBarInfo.rcTitleBar.top) + 2 * (int)info.cyWindowBorders; _extraWindowWidth = 2 * (int)info.cxWindowBorders; Rectangle rcClient = new Rectangle(0, 0, 0, 0); // Get client rectangle of dialog RECT rcTemp = new RECT(); User32.GetWindowRect(_hWndParent, ref rcTemp); rcClient.X = rcTemp.left; rcClient.Y = rcTemp.top; rcClient.Width = rcTemp.Width; rcClient.Height = rcTemp.Height + TABS_HEIGHT + BUTTONS_HEIGHT; //make the dialog box bigger User32.MoveWindow(_hWndParent, rcClient.Left, rcClient.Top, rcClient.Width, rcClient.Height, true); //move all the controls down AdjustControlLocations(); //top tab control mainTabControl = new LightweightControlContainerControl(); User32.SetParent(mainTabControl.Handle, _hWndParent); mainTabControl.Location = new Point(0, 0); mainTabControl.Anchor = AnchorStyles.Left | AnchorStyles.Right; mainTabControl.Size = new Size(rcClient.Width, TABS_HEIGHT); tabs = new TabLightweightControl(); tabs.ColorizeBorder = false; tabs.VirtualBounds = new Rectangle(0, 0, rcClient.Width, TABS_HEIGHT); tabs.LightweightControlContainerControl = mainTabControl; tabs.DrawSideAndBottomTabPageBorders = false; InsertImageTabControl tabFromFile = new InsertImageTabControl(); tabFromFile.TabText = Res.Get(StringId.InsertImageInsertFromFile); tabFromFile.TabBitmap = ResourceHelper.LoadAssemblyResourceBitmap("ImageInsertion.Images.TabInsertFromFile.png"); tabFromFile.BackColor = SystemColors.Control; User32.SetParent(tabFromFile.Handle, _hWndParent); tabs.SetTab(0, tabFromFile); mainTabControl.BackColor = tabFromFile.ApplicationStyle.InactiveTabTopColor; //now, add tabs for the other controls int i = 1; foreach (InsertImageSource imageSource in imageSources) { InsertImageTabControl tab = new InsertImageTabControl(); tab.TabText = imageSource.TabName; tab.TabBitmap = imageSource.TabBitmap; tab.BackColor = SystemColors.Control; tabs.SetTab(i++, tab); } tabs.SelectedTabNumberChanged += new EventHandler(tabs_SelectedTabNumberChanged); //set the keyboard hook for tab switching tabKeyboardHook = new TabbingHookProc(tabs); tabKeyboardHook.Install(_hWndParent); //add other image source panels _panelImage = new Panel(); _panelImage.Location = new Point(0, mainTabControl.Size.Height); _panelImage.BorderStyle = BorderStyle.None; _panelImage.Anchor = AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top | AnchorStyles.Bottom; _panelImage.Size = new Size(rcClient.Width, rcClient.Height - TABS_HEIGHT - BUTTONS_HEIGHT - _extraWindowHeight); _panelImage.Visible = false; User32.SetParent(_panelImage.Handle, _hWndParent); //initalize the other sources foreach (InsertImageSource source in imageSources) { source.Init(_panelImage.Width, _panelImage.Height); Control c = source.ImageSelectionControls; DisplayHelper.Scale(c); foreach (Control childControl in c.Controls) DisplayHelper.Scale(childControl); } DisplayHelper.Scale(_panelImage); //special cancel button _buttonPanel = new Panel(); _buttonPanel.Location = new Point(rcClient.Width - (int)(0.5 * _extraWindowWidth) - _buttonPanel.Width, _panelImage.Bounds.Bottom); _buttonPanel.Size = new Size(75, 23); _buttonPanel.BorderStyle = BorderStyle.None; _cancelButton = new Button(); _cancelButton.TextAlign = ContentAlignment.MiddleCenter; if (BidiHelper.IsRightToLeft) _cancelButton.RightToLeft = RightToLeft.Yes; _cancelButton.Text = Res.Get(StringId.CancelButton); _cancelButton.FlatStyle = FlatStyle.System; _cancelButton.Location = new Point(0, 0); _cancelButton.Size = new Size(75, 23); _cancelButton.Click += new EventHandler(_cancelButton_Click); _buttonPanel.Controls.Add(_cancelButton); User32.SetParent(_buttonPanel.Handle, _hWndParent); int origWidth = _cancelButton.Width; string tmp = _cancelButton.Text; _cancelButton.Text = Res.Get(StringId.InsertImageButton); int newWidth = Math.Max(origWidth, DisplayHelper.MeasureButton(_cancelButton)); _cancelButton.Text = tmp; newWidth = Math.Max(newWidth, DisplayHelper.MeasureButton(_cancelButton)); _buttonPanel.Width = _cancelButton.Width = newWidth; int deltaX = newWidth - origWidth; _buttonPanel.Left -= deltaX; //fixing up button text and tab order IntPtr hWndOpenButton = User32.GetDlgItem(_hWndParent, _OPEN_BUTTON_ID); User32.SetWindowText(hWndOpenButton, Res.Get(StringId.InsertImageButton)); mainTabControl.InitFocusManager(); mainTabControl.AddFocusableControls(tabs.GetAccessibleControls()); foreach (InsertImageSource tabPage in imageSources) mainTabControl.AddFocusableControl(tabPage.ImageSelectionControls); state = STATE.FILE; return IntPtr.Zero; } case WM.SIZE: { ManipulatePanels(); return IntPtr.Zero; } // WM_NOTIFY - we're only interested in the CDN_SELCHANGE notification message: // we grab the currently-selected filename and copy it into the buffer case WM.NOTIFY: { IntPtr ipNotify = new IntPtr(lParam); OfNotify ofNot = (OfNotify)Marshal.PtrToStructure(ipNotify, typeof(OfNotify)); Int16 code = (short)ofNot.hdr.code; if (code == CommonDlgNotification.SelChange) { UpdateChosenImage(false); //CheckOptions(false); } else if (code == CommonDlgNotification.InitDone) { listener = new CommandListener(_hWndParent, this, (int)User32.GetDlgCtrlID(_cancelButton.Handle)); } else if (code == CommonDlgNotification.FileOk) { // update the image path (need to do this if the user selected // a file by simpliy typing in the filepath text box) UpdateChosenImage(true); // ok to insert _insertFile = true; } else if ((code == CommonDlgNotification.FolderChange) && (state == STATE.WEB)) { // If the user hits the OK button while there is no valid selection // within the File panel, the file dialog sends a CommonDlgNotification.FolderChange // We use this combined with other relevant state to trigger the closing // of the Image dialog HitOpen(); } return IntPtr.Zero; } } } catch (Exception ex) { UnexpectedErrorMessage.Show(ex); return new IntPtr(1); } finally { GC.KeepAlive(this); } }