Скрытие winform и возвращение его из DLL - PullRequest
0 голосов
/ 28 мая 2011

В моем DDL определена следующая функция:

extern "C" __declspec(dllexport) void hideme(HWND h) {
    //ShowWindow(h, SW_HIDE);
    SendMessage(h, WM_SHOWWINDOW, FALSE, 0);
}

Как видите, я пробовал несколько вещей, чтобы это работало ...

У меня в объявленной форме объявлено следующее:

typedef void (*HideMe)(HWND); 

В моем событии System :: Windows :: Forms :: Form Load у меня есть следующий код:

...
HINSTANCE hinst = LoadLibrary(_T("My.dll"));
if (hinst == NULL)
    System::Diagnostics::Debug::WriteLine("null hinst"); 
else
    hideme = (HideMe) GetProcAddress(hinst, "hideme");
...

В моем событии System :: Windows :: Forms :: Form Shown у меня есть следующий код:

...
hideme((HWND)this->Handle.ToPointer());
...

Я думаю, что проблема должна заключаться в том, как я отправляю через HWND, но я искал весь день и не могу найти альтернативу.

Я также пытался установить this-> Visible = false; но тогда я не могу понять, как вызвать его обратно в видимый из DLL (злоупотребление sendmessage?).

Я не программист на C ++, обычно я программирую только на управляемых языках, поэтому любая помощь (и терпение приветствуется.

Спасибо

Ник.

нотабене

Одна странная вещь, которую я не могу объяснить, это то, что я не могу вызвать ShowWindow из самой WinForm. Это бросит этот драгоценный камень:

Error   2   error LNK2028: unresolved token (0A00001E) "extern "C" int __stdcall ShowWindow(struct HWND__ *,int)" (?ShowWindow@@$$J18YGHPAUHWND__@@H@Z) referenced in function "private: void __clrcall CheckMSNCpp::frmMain::frmMain_Shown(class System::Object ^,class System::EventArgs ^)" (?frmMain_Shown@frmMain@CheckMSNCpp@@$$FA$AAMXP$AAVObject@System@@P$AAVEventArgs@4@@Z)
Error   3   error LNK2019: unresolved external symbol "extern "C" int __stdcall ShowWindow(struct HWND__ *,int)" (?ShowWindow@@$$J18YGHPAUHWND__@@H@Z) referenced in function "private: void __clrcall CheckMSNCpp::frmMain::frmMain_Shown(class System::Object ^,class System::EventArgs ^)" (?frmMain_Shown@frmMain@CheckMSNCpp@@$$FA$AAMXP$AAVObject@System@@P$AAVEventArgs@4@@Z)
Error   4   error LNK1120: 2 unresolved externals

[EDIT1]

Ганс Пассант сказал:

Сообщение об ошибке компоновщика, которое вы получили попытка ShowWindow () также Сильный намек, почему ваш текущий код не работает. Вы забыли добавить ошибку проверяя код, GetProcAddress () может потерпеть неудачу и вернет нулевой указатель. Будет, функция не экспортируется по имени "hideme". В 32-битном построить, он будет экспортирован как "_hideme", обратите внимание на подчеркивание. Который был добавлен, чтобы указать, что функция использует вызов __cdecl условность. Ошибка компоновщика на ShowWindow демонстрирует имя C ++ украшения, вы забыли включить windows.h и придумал свой, неверно, объявление для ShowWindow.

Это не правильный способ сделать это, Вы должны просто установить Visible свойство ложно. Как ты и пытался. Зачем Вы не можете установить его обратно в истину совершенно неузнаваемо.

То, что вы сказали, не имеет никакого смысла для меня по нескольким причинам.

1)

Импорт для winform:

#include "stdafx.h"
#include <windows.h>
#include <iostream>
#include <stdio.h>

Как вы можете сказать, там есть windows.h.

2) Ошибка ShowWindor отсутствует в DLL, там я могу назвать это нормально, она есть в коде WinForm.

3) Я никогда не экспортировал ShowWindow, только мои собственные функции.

[/ EDIT1]

[EDIT2] Уве Кейм сказал:

Зачем вам нужна дополнительная DLL, которая просто просто обертка в другую DLL функционировать?

Я бы сделал это, как, например, C # с помощью PInvoke из вашего управляемого C ++ приложение. Подпись для SendMessage будет (в C #):

Материал PInvoke просто не имеет никакого смысла, как говорили комментаторы.

Что касается DLL, она должна быть DLL, потому что мне требуется глобальный хук для ответа на мои горячие клавиши & WH_CBT. В этом случае я хочу, чтобы программа запускалась скрытой и просто показывала экран настроек при нажатии комбинации клавиш.

Все в программе работает, как и ожидалось, горячая клавиша работает как шарм, единственное слабое место, которое я не могу понять, показывает приложение, запущенное из DLL. [/ EDIT2] * * один тысяча шестьдесят-семь

[EDIT3] Пример кода по адресу: http://www.nickkusters.com/CPP_PROBLEM_Demo-NOBIN.zip [/ EDIT3] * +1071 *

Ответы [ 2 ]

1 голос
/ 28 мая 2011

Сообщение об ошибке компоновщика, которое вы получили при попытке ShowWindow (), также является сильной подсказкой, почему ваш текущий код не работает.Вы забыли добавить код проверки ошибок, GetProcAddress () может завершиться ошибкой и вернет нулевой указатель.Да, функция не экспортируется именем «hideme».В 32-битной сборке он будет экспортирован как "_hideme", обратите внимание на подчеркивание.Который был добавлен, чтобы указать, что функция использует соглашение о вызовах __cdecl.Ошибка компоновщика в ShowWindow демонстрирует оформление имени в C ++, вы забыли #include windows.h и создали свое собственное, неправильное объявление для ShowWindow.

Это не правильный способ сделать это, вы должны просто установитьВидимое свойство ложно.Как ты и пытался.Почему вы не можете установить его обратно в истину, совершенно невозможно понять.

0 голосов
/ 28 мая 2011

Зачем вам нужна дополнительная DLL, которая просто является оберткой для другой функции DLL?

Я бы сделал это, например, в C # на , используя PInvoke из вашего управляемого приложения C ++ .Подпись для SendMessage будет (в C #):

[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(
    IntPtr hWnd, 
    UInt32 Msg, 
    IntPtr wParam, 
    IntPtr lParam);
...