Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > ToolTip в другом окне.


Автор: SqueeZe 2.10.2009, 02:26
Пробую отобразить тултип для другого окна.


Код

public class WindowWrapper : System.Windows.Forms.IWin32Window {
public WindowWrapper(IntPtr handle) { _hwnd = handle; }
public IntPtr Handle { get { return _hwnd; } }
private IntPtr _hwnd;
}


В принципе все просто, но следующий код выбивает исключение.

Код

ToolTip tt = new ToolTip();
tt.ShowAlways = true;
tt.Show("Hello", new WindowWrapper(hWnd), 100, 100);


I get a "NullObjectReference Exception" - Object reference not set to an instance of an object. at 

Но почему то MessageBox, принимающий тот же объект, срабатывает на отлично!

Код

MessageBox.Show(new WindowWrapper(hWnd), "Hello World!");


Откуда появляется это исключение, и что, собственно делать. Перерыл весь инет - ничего не нашел по этой теме.

Сразу скажу, задача - отображение ToolTip на полноэкранном Direct3D. Причем тот же autoit прекрасно справляется с этой задачей, но исходников его тоже нарыть не удалось. 

С Уважением, Константин.

Автор: diadiavova 2.10.2009, 13:13
Вообще-то в описании метода ToolTip.Show о параметре window написано буквально следующее
Цитата

window: Элемент управления System.Windows.Forms.Control, для которого отображается всплывающая подсказка.
Видимо причина в том, что то окошко не является System.Windows.Forms.Control

Автор: SqueeZe 2.10.2009, 17:08
И какие могут быть варианты решения данной проблемы?

Автор: mr.DUDA 4.10.2009, 13:44
Можно вызвать NativeWindowControl.CreateFromHandle из handle окна, и для созданного контрола показать тултип:
Код

    public class NativeWindowControl : Control
    {
        private NativeWindowControl() { }

        [DllImport("user32.dll")]
        static extern IntPtr GetParent(IntPtr handle);
        [DllImport("user32.dll")]
        static extern int GetWindowThreadProcessId(IntPtr handle, ref int processId);

        public static NativeWindowControl CreateFromHandle(IntPtr handle)
        {
            // create control...
            NativeWindowControl ret = new NativeWindowControl();
            FieldInfo fi = typeof(Control).GetField("window", BindingFlags.NonPublic | BindingFlags.Instance);
            NativeWindow wnd = (NativeWindow)fi.GetValue(ret);
            wnd.AssignHandle(handle);
            ret.OnHandleCreated(EventArgs.Empty);
            ret.UpdateBounds();

            // ...and form
            Form form = new Form();
            IntPtr tmpHandle = handle, parentHandle = handle;
            int unused = 0;
            int currThreadId = GetWindowThreadProcessId(handle, ref unused);
            while ((tmpHandle = GetParent(parentHandle)) != IntPtr.Zero)
            {
                if (GetWindowThreadProcessId(tmpHandle, ref unused) != currThreadId)
                    break;
                parentHandle = tmpHandle;
            }
            wnd = (NativeWindow)fi.GetValue(form);
            wnd.AssignHandle(parentHandle);
            MethodInfo mi = typeof(Form).GetMethod("OnHandleCreated", BindingFlags.NonPublic | BindingFlags.Instance);
            mi.Invoke(form, new object[] { EventArgs.Empty });
            mi = typeof(Form).GetMethod("UpdateBounds", BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null);
            mi.Invoke(form, new object[0]);
            form.Visible = true;

            // bind them together
            fi = typeof(Control).GetField("parent", BindingFlags.NonPublic | BindingFlags.Instance);
            fi.SetValue(ret, form);

            return ret;
        }

        protected override void CreateHandle()
        {
        }
    }


 smile 

Автор: SqueeZe 4.10.2009, 20:04
Интересно, но на 17 строке цепляется к коду: "Недопустимая операция в нескольких потоках: попытка доступа к элементу управления "" не из того потока, в котором он был создан."

Автор: mr.DUDA 4.10.2009, 23:55
Эту проверку можно вырубить:
Код
Control.CheckForIllegalCrossThreadCalls = false;

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)