How to get an anchor window to accept inserting from the clipboard

Started by Yacine, December 19, 2015, 08:16:28 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Yacine

Hi guys,
I have a modeless dialog with a text control that accepts inserting from the clipboard.
When I try to put this dialog in an anchor window, the inserting goes straight to the drawing window. It creates a shape with the text I tried to insert in the text box.
I used the standard code for the anchor window.
Public Sub ShowForm()
    Dim vsoWindow As Visio.Window
    Dim frmNewWindow As UserForm
    Dim lngFormHandle As Long
    Dim pnLeft As Long, pnTop As Long, pnWidth As Long, pnHeight As Long
    Dim myWindowName As String
    myWindowName = "Behaviour"
   

    Set vsoWindow = ActiveWindow.Windows.Add(myWindowName, visWSVisible + visWSDockedLeft, visAnchorBarAddon, , , 350, 210)
    Set frmNewWindow = New SetBehaviour
    lngFormHandle = FindWindow(vbNullString, myWindowName)
    SetWindowLong lngFormHandle, GWL_STYLE, WS_CHILD Or WS_VISIBLE
    SetParent lngFormHandle, vsoWindow.WindowHandle32
   
    vsoWindow.GetWindowRect pnLeft, pnTop, pnWidth, pnHeight
    vsoWindow.SetWindowRect pnLeft, pnTop, pnWidth + 1, pnHeight
End Sub


From the fact that the text box behaviour was fine, when being in a regular dialog (form), I deduce that it has nothing to do with the settings of the text box or the form.
The place to look at is probably "SetWindowLong lngFormHandle, GWL_STYLE, WS_CHILD Or WS_VISIBLE", for which I found the following 2 links, but the setting combinations are quite numerous.

https://msdn.microsoft.com/de-de/library/windows/desktop/ms633591%28v=vs.85%29.aspx
https://msdn.microsoft.com/de-de/library/windows/desktop/ms632600%28v=vs.85%29.aspx

Would anyone have a suggestion?
Thanks in advance.
Yacine

Nikolay

The problem here most probably is that Visio intercepts some keyboard shortcuts (such as copy/paste) before they even hit your window.
No matter what you do with your window, it won't help.

The solution here is to use OnKeystrokeMessageForAddon event, that was specifically introduced to overcome that:
https://msdn.microsoft.com/en-us/library/office/ff765211.aspx

Can copy my code here (C#, but I think that still may be helpful):
Sorry for a bit clumsy code, it wasn't initially meat to be public... also note taht you may need to replace "FastColoredTextBox" with your form class for which you want to process shortcuts.
Also yu probably need just 2 shortcuts - Ctrl+C/Ctrl+V (the code below processes a few dozens). Anyways, hope this helps. :)


    /// somewhere in main code
    _shortcutManager = new ShortcutManager();
    Application.OnKeystrokeMessageForAddon += _shortcutManager.OnKeystrokeMessageForAddon;

    // the class to process shortcuts
    public class ShortcutManager
    {
        private static HashSet<Keys> KeysFromString(string keys)
        {
            var cult = Thread.CurrentThread.CurrentUICulture;
            Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture;

            var kc = new KeysConverter();
            var result = new HashSet<Keys>(
                keys
                    .Split(',')
                    .Select(s => s.Trim())
                    .Select(kc.ConvertFromString)
                    .Cast<Keys>()
                    .ToList());

            Thread.CurrentThread.CurrentUICulture = cult;
            return result;
        }

        private static readonly Lazy<HashSet<Keys>> ControlShortcutKeys = new Lazy<HashSet<Keys>>(() =>
            KeysFromString(
                "Tab, Tab+Shift, Tab+Ctrl, Ctrl+Shift+Tab, " +
                "Escape, PgUp, PgDn, End, Home, Left, Up, Right, Down, Ins, " +
                "Del, F3, Shift+PgUp, Shift+PgDn, Shift+End, Shift+Home, Shift+Left, " +
                "Shift+Up, Shift+Right, Shift+Down, Shift+Ins, Shift+Del, Ctrl+Back, Ctrl+Space, Ctrl+End, " +
                "Ctrl+Home, Ctrl+Left, Ctrl+Up, Ctrl+Right, Ctrl+Down, Ctrl+Ins, Ctrl+Del, Ctrl+0, Ctrl+A, " +
                "Ctrl+B, Ctrl+C, Ctrl+E, Ctrl+F, Ctrl+G, Ctrl+H, Ctrl+I, Ctrl+M, Ctrl+N, Ctrl+R, Ctrl+Y, Ctrl+U, " +
                "Ctrl+V, Ctrl+X, Ctrl+Z, Ctrl+Add, Ctrl+Subtract, Ctrl+OemMinus, Ctrl+Shift+End, " +
                "Ctrl+Shift+Home, Ctrl+Shift+Left, Ctrl+Shift+Right, Ctrl+Shift+B, Ctrl+Shift+C, Ctrl+Shift+N, " +
                "Ctrl+Shift+U, Ctrl+Shift+OemMinus, Alt+Back, Alt+Up, Alt+Down, Alt+F, Alt+Shift+Left, " +
                "Alt+Shift+Up, Alt+Shift+Right, Alt+Shift+Down"));

        private static readonly Lazy<HashSet<Keys>> FormShortcutKeys = new Lazy<HashSet<Keys>>(() =>
            KeysFromString("Tab, Tab+Shift"));

        public bool OnKeystrokeMessageForAddon(Visio.MSGWrap msgWrap)
        {
            var keys = (Keys) msgWrap.wParam;
            if ((Control.ModifierKeys & Keys.Control) != 0)
                keys |= Keys.Control;
            if ((Control.ModifierKeys & Keys.Shift) != 0)
                keys |= Keys.Shift;

            var control = Control.FromChildHandle((IntPtr) msgWrap.hwnd);
            if (control == null)
                return false;

            var form = control.FindForm();
            if (form != null && !(control is FastColoredTextBox))
            {
                if (FormShortcutKeys.Value.Contains(keys))
                {
                    var message = new Message
                    {
                        HWnd = (IntPtr)msgWrap.hwnd,
                        Msg = msgWrap.message,
                        WParam = (IntPtr)msgWrap.wParam,
                        LParam = (IntPtr)msgWrap.lParam,
                    };

                    if (form.PreProcessMessage(ref message))
                        return true;
                }
            }

            if (ControlShortcutKeys.Value.Contains(keys))
            {
                var msg = new MSG
                {
                    hwnd = (IntPtr)msgWrap.hwnd,
                    message = msgWrap.message,
                    wParam = (IntPtr)msgWrap.wParam,
                    lParam = (IntPtr)msgWrap.lParam
                };

                NativeMethodsUI.TranslateMessage(ref msg);
                NativeMethodsUI.DispatchMessage(ref msg);
                return true;
            }

            return false;
        }
    }

    #region WINAPI

    public static class NativeMethodsUI
    {
        [DllImport("user32", EntryPoint = "DispatchMessage")]
        public static extern IntPtr DispatchMessage(ref MSG lpMsg);

        [DllImport("user32", EntryPoint = "TranslateMessage")]
        public static extern bool TranslateMessage(ref MSG lpMsg);
    }

    #endregion

Yacine

Большое спасибо. Я знал, что все члены, вы бы тот, кто может ответить на это.
(https://translate.google.de/)
Yacine

AndyW

Although not with an anchored window, I had to do something similar for drag-and-drop. I ended up having to handle the windows messages for the form. Initially the WIndow Activate to set a flag, then the Window Activate App message, in the latter, if the flag was set (and my form was visible) I set focus to my form so that it got the drop rather than the Visio window.
Live life with an open mind

Yacine

Thanks Andy. That are really not problems, one likes to care about.
Yacine