i need to open a word document in a panel control of Windows Forms Application to view/edit file and save.
i use this statement :
[DllImport("user32.dll")]
public static extern int FindWindow(string strclassName, string strWindowName);
[DllImport("user32.dll")]
static extern int SetParent(int hWndChild, int hWndNewParent);
[DllImport("user32.dll", EntryPoint = "SetWindowPos")]
static extern bool SetWindowPos(
int hWnd, // handle to window
int hWndInsertAfter, // placement-order handle
int X, // horizontal position
int Y, // vertical position
int cx, // width
int cy, // height
uint uFlags // window-positioning options
);
[DllImport("user32.dll", EntryPoint = "MoveWindow")]
static extern bool MoveWindow(
int hWnd,
int X,
int Y,
int nWidth,
int nHeight,
bool bRepaint
);
const int SWP_DRAWFRAME = 0x20;
const int SWP_NOMOVE = 0x2;
const int SWP_NOSIZE = 0x1;
const int SWP_NOZORDER = 0x4;
const int SWP_FRAMECHANGED = 0x20;
ToolsComponents.MSWord word = new ToolsComponents.MSWord();
private void toolStripButton2_Click(object sender, EventArgs e)
{
word.CreateWordDocument();
word.OpenFile(#"C:\Users\ME\Documents\test.docx", true);
int wordWnd = FindWindow("Opusapp", null);
if (wordWnd != 0)
{
int ret = SetParent(wordWnd, pnlShowForm.Handle.ToInt32());
//int ret2 = FindWindow("Opusapp", null);
//ret = SetParent(wordWnd, pnlShowForm.Handle.ToInt32());
SetWindowPos(wordWnd, pnlShowForm.Handle.ToInt32(), 0, 0, pnlShowForm.Bounds.Width - 20, pnlShowForm.Bounds.Height - 20, SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOMOVE | SWP_DRAWFRAME);
MoveWindow(wordWnd, -5, -33, pnlShowForm.Bounds.Width + 10, pnlShowForm.Bounds.Height + 57, true);
}
}
private void frmDocumentManager_FormClosing(object sender, FormClosingEventArgs e)
{
if (word != null)
{
word.CloseDoc(true);
word.Quit();
}
but this is not a good solution and have problem in runtime.
in sometimes MS word and document started outside the form and i can't control this.
Related
This question already has answers here:
RichTextBox syntax highlighting in real time--Disabling the repaint
(3 answers)
Closed 2 years ago.
I'm doing a text editor based on RichTextBox. It has to handle complex formatting (BIU, colored text, etc). The problem is that all formatting tools are selection based, e.g. i have to select piece of text, format it, select next, etc.
it takes time, and it is visible for user.
is there a way to turn-off RichTextBox redraw, then do formatting, then turn-on redraw?
Or maybe any other way to handel complex formatting quickly?
Decision found and it's working.
Wrote a wrap-class using this code
Class itself:
public class RichTextBoxRedrawHandler
{
RichTextBox rtb;
public RichTextBoxRedrawHandler (RichTextBox _rtb)
{
rtb = _rtb;
}
[DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, int wMsg, int wParam, ref Point lParam);
[DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, int wMsg, int wParam, IntPtr lParam);
const int WM_USER = 1024;
const int WM_SETREDRAW = 11;
const int EM_GETEVENTMASK = WM_USER + 59;
const int EM_SETEVENTMASK = WM_USER + 69;
const int EM_GETSCROLLPOS = WM_USER + 221;
const int EM_SETSCROLLPOS = WM_USER + 222;
private Point _ScrollPoint;
private bool _Painting = true;
private IntPtr _EventMask;
private int _SuspendIndex = 0;
private int _SuspendLength = 0;
public void SuspendPainting()
{
if (_Painting)
{
_SuspendIndex = rtb.SelectionStart;
_SuspendLength = rtb.SelectionLength;
SendMessage(rtb.Handle, EM_GETSCROLLPOS, 0, ref _ScrollPoint);
SendMessage(rtb.Handle, WM_SETREDRAW, 0, IntPtr.Zero);
_EventMask = SendMessage(rtb.Handle, EM_GETEVENTMASK, 0, IntPtr.Zero);
_Painting = false;
}
}
public void ResumePainting()
{
if (!_Painting)
{
rtb.Select(_SuspendIndex, _SuspendLength);
SendMessage(rtb.Handle, EM_SETSCROLLPOS, 0, ref _ScrollPoint);
SendMessage(rtb.Handle, EM_SETEVENTMASK, 0, _EventMask);
SendMessage(rtb.Handle, WM_SETREDRAW, 1, IntPtr.Zero);
_Painting = true;
rtb.Invalidate();
}
}
}
Usage:
RichTextBoxRedrawHandler rh = new RichTextBoxRedrawHandler(richTextBoxActually);
rh.SuspendPainting();
// do things with richTextBox
rh.ResumePainting();
I'm trying to figure out how this code works but I just can not figure out what makes it click through.
Yes, this code is not mine since i'm trying to learn/understand it.
Assume I want the tranparancy but not the click through what needs to be changed and why?
I have been over the Windows styles pages over and over and still can not get my head around the click through part.
using System;
using System.Runtime.InteropServices;
using UnityEngine;
public class TransparentWindow : MonoBehaviour
{
[SerializeField]
private Material m_Material;
private struct MARGINS
{
public int cxLeftWidth;
public int cxRightWidth;
public int cyTopHeight;
public int cyBottomHeight;
}
[DllImport("user32.dll")]
private static extern IntPtr GetActiveWindow();
[DllImport("user32.dll")]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, uint dwNewLong);
[DllImport("user32.dll")]
static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
[DllImport("user32.dll", EntryPoint = "SetLayeredWindowAttributes")]
static extern int SetLayeredWindowAttributes(IntPtr hwnd, int crKey, byte bAlpha, int dwFlags);
[DllImport("user32.dll", EntryPoint = "SetWindowPos")]
private static extern int SetWindowPos(IntPtr hwnd, int hwndInsertAfter, int x, int y, int cx, int cy, int uFlags);
[DllImport("Dwmapi.dll")]
private static extern uint DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS margins);
const int GWL_STYLE = -16;
const uint WS_POPUP = 0x80000000;
const uint WS_VISIBLE = 0x10000000;
const int HWND_TOPMOST = -1;
void Start()
{
#if !UNITY_EDITOR // You really don't want to enable this in the editor..
int fWidth = Screen.width;
int fHeight = Screen.height;
var margins = new MARGINS() { cxLeftWidth = -1 };
var hwnd = GetActiveWindow();
SetWindowLong(hwnd, GWL_STYLE, WS_POPUP | WS_VISIBLE);
// Transparent windows with click through
SetWindowLong(hwnd, -20, 524288 | 32);//GWL_EXSTYLE=-20; WS_EX_LAYERED=524288=&h80000, WS_EX_TRANSPARENT=32=0x00000020L
SetLayeredWindowAttributes(hwnd, 0, 255, 2);// Transparency=51=20%, LWA_ALPHA=2
SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, fWidth, fHeight, 32 | 64); //SWP_FRAMECHANGED = 0x0020 (32); //SWP_SHOWWINDOW = 0x0040 (64)
DwmExtendFrameIntoClientArea(hwnd, ref margins);
#endif
}
void OnRenderImage(RenderTexture from, RenderTexture to)
{
Graphics.Blit(from, to, m_Material);
}
}
This function:
SetWindowLong(hwnd, -20, 524288 | 32);
does the trick. Windows implements the rule that Mircosoft made which is that a window that is transparent to the user must be transparent to the mouse.
With the transparency bit set WS_EX_TRANSPARENT the window becomes transparent to mouse too and click passes to the painted layer behind the transparent window.
You need not understand but make use of this 'OS feature' which was probably implemented to cover for something else.
Read this article about the subject and this answer that explains the parameters
I'm trying to put the Virtual Keyboard of Win 10 Borderless
But don't know why it's not working.
I tried with NotePad and it's working.
( I did a Debug.log to check if IntPtr is not null and in both case it return true)
Here's what I did
using UnityEngine;
using System;
using System.Runtime.InteropServices;
public class test : MonoBehaviour
{
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string className, string windowName);
[DllImport("USER32.DLL")]
public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
[DllImport("USER32.DLL")]
public static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags);
const int WS_BORDER = 8388608;
const int WS_DLGFRAME = 4194304;
const int WS_CAPTION = WS_BORDER | WS_DLGFRAME;
const int WS_SYSMENU = 524288;
const int WS_THICKFRAME = 262144;
const int WS_MINIMIZE = 536870912;
const int WS_MAXIMIZEBOX = 65536;
const int GWL_STYLE = -16;
const int GWL_EXSTYLE = -20;
const int WS_EX_DLGMODALFRAME = 0x1;
const int SWP_NOMOVE = 0x2;
const int SWP_NOSIZE = 0x1;
const int SWP_FRAMECHANGED = 0x20;
const uint MF_BYPOSITION = 0x400;
const uint MF_REMOVE = 0x1000;
private void Borderless() {
// IntPtr hWnd = FindWindow(null,"On-Screen Keyboard"); // <----- Not Working
IntPtr hWnd = FindWindow(null,"Untitled - NotePad"); // <----- Working
if (hWnd != IntPtr.Zero)
{
int Style = 0;
Style = GetWindowLong(hWnd, GWL_STYLE);
Style = Style & ~WS_CAPTION;
Style = Style & ~WS_SYSMENU;
Style = Style & ~WS_THICKFRAME;
Style = Style & ~WS_MINIMIZE;
Style = Style & ~WS_MAXIMIZEBOX;
SetWindowLong(hWnd, GWL_STYLE, Style);
Style = GetWindowLong(hWnd, GWL_EXSTYLE);
SetWindowLong(hWnd, GWL_EXSTYLE, Style | WS_EX_DLGMODALFRAME);
SetWindowPos(hWnd, new IntPtr(0), 50, 0, 150, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
}
else
{
Debug.LogWarning("Borderless() failed, hWnd is 0!");
}
}
void Start()
{
Borderless();
}
}
Thanks Guys ;)
Ok I get another Solution, Maybe a better one.
On-Screen Keyboard on Unity
I know it's not a real answer so if someone know why the code above is not working, I'll be glad to learn ;)
I have a window in an application, and the Resize mode is set to NoResize, but if you click the top-left of the window, the menu items of "Maximize", "Minimize", and "Size" are still enabled. This only happens to my windows that has no icon but still has the close button. Meaning this problem isn't happening to my windows that do have an icon.
This is the code that is removing the icon but still keeps the red close button:
protected override void OnSourceInitialized(EventArgs e) {
IconHelper.RemoveIcon(this);
}
public static class IconHelper {
[DllImport("user32.dll")]
static extern int GetWindowLong(IntPtr hwnd, int index);
[DllImport("user32.dll")]
static extern int SetWindowLong(IntPtr hwnd, int index, int newStyle);
[DllImport("user32.dll")]
static extern bool SetWindowPos(IntPtr hwnd, IntPtr hwndInsertAfter, int x, int y, int width, int height, uint flags);
[DllImport("user32.dll")]
static extern IntPtr SendMessage(IntPtr hwnd, uint msg, IntPtr wParam, IntPtr lParam);
const int GWL_EXSTYLE = -20;
const int WS_EX_DLGMODALFRAME = 0x0001;
const int SWP_NOSIZE = 0x0001;
const int SWP_NOMOVE = 0x0002;
const int SWP_NOZORDER = 0x0004;
const int SWP_FRAMECHANGED = 0x0020;
const uint WM_SETICON = 0x0080;
public static void RemoveIcon(Window window) {
IntPtr hwnd = new WindowInteropHelper(window).Handle;
int extendedStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
SetWindowLong(hwnd, GWL_EXSTYLE, extendedStyle | WS_EX_DLGMODALFRAME);
SetWindowPos(hwnd, IntPtr.Zero, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
}
}
I would like to know why this is happening and would appreciate it if some one can fix this problem. I am using WPF and C#.
I'm opening up a new Outlook email from code in my windows application. Is there a way to give focus to the new window (instead of blinking orange behind)?
Thank you!
Try using the PInvoke:
public class MoveToForeground
{
[DllImportAttribute("User32.dll")]
private static extern int FindWindow(string ClassName, string WindowName);
[DllImport("user32.dll", EntryPoint="SetWindowPos")]
public static extern IntPtr SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int Y, int cx, int cy, int wFlags);
const int SWP_NOMOVE = 0x0002;
const int SWP_NOSIZE = 0x0001;
const int SWP_SHOWWINDOW = 0x0040;
const int SWP_NOACTIVATE = 0x0010;
public static void DoOnProcess(string processName)
{
var process = Process.GetProcessesByName(processName);
if (process.Length > 0)
{
int hWnd = FindWindow(null, process[0].MainWindowTitle.ToString());
SetWindowPos(new IntPtr(hWnd), 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | SWP_NOACTIVATE);
}
}
}
MoveToForeground.DoOnProcess("OUTLOOK.EXE");