FindWindowEx от пользователя 32.dll возвращает дескриптор нуля и код ошибки 127 с помощью dllimport

мне нужно обработать другое приложение windows программно, поиск google я нашел образец, который обрабатывает калькулятор windows с помощью атрибута DLLImport и импортирует user32.dll-функции в управляемые в C#.

приложение работает, я получаю дескриптор для главного окна, т. е. самого калькулятора, но впоследствии код не работает. Метод FindWindowEx не возвращает дескрипторы дочерних элементов калькулятора, таких как кнопки и текстовый.

Я попытался использовать SetLastError=True на DLLImport и обнаружил, что я получаю код ошибки 127, который является "процедура не найдена".

Это ссылка, по которой я получил пример приложения:

http://www.codeproject.com/script/Articles/ArticleVersion.aspx?aid=14519&av=34503

пожалуйста, помогите, если кто знает как решить.

обновление: DLLImport:

[DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className,  string  windowTitle);

код не работает:

hwnd=FindWindow(null,"Calculator"); // This is working, I am getting handle of Calculator

// The following is not working, I am getting hwndChild=0 and err = 127
hwndChild = FindWindowEx((IntPtr)hwnd,IntPtr.Zero,"Button","1");

                Int32 err = Marshal.GetLastWin32Error();

3 ответов


код, который вы пытаетесь, полагается на подписи отдельных кнопок для их идентификации. Например, для получения дескриптора кнопки "1" используется следующий код:

hwndChild = FindWindowEx((IntPtr)hwnd, IntPtr.Zero, "Button", "1");

который указывает " Button "для имени класса окна и" 1 " для имени окна (в случае кнопки это то же самое, что и текст заголовка, отображаемый на самой кнопке).

этот код отлично работал под Windows XP( и в предыдущих версиях), где калькулятор кнопки были идентифицированы с текстовыми подписями. Кнопка " 1 "имела имя окна" 1", и, таким образом," 1 " отображался в качестве заголовка кнопки.

однако, похоже, что все изменилось под Windows 7 (возможно, и под Vista, хотя я не могу проверить это, потому что у меня нет доступа к такой системе). Использование Spy++ для исследования окна калькулятора подтверждает, что кнопка " 1 "больше не имеет имени окна"1". На самом деле, у него вообще нет имени окна; заголовок имеет значение NULL. Предположительно, новый причудливый вид калькулятора требовал, чтобы кнопки были нарисованы на заказ, поэтому подписи больше не нужны, чтобы указать, какая кнопка соответствует какой функции. Пользовательские процедуры рисования позаботятся о рисовании необходимых подписей.

поскольку кнопка не может быть найдена с указанным вами текстом окна, значение 0 (NULL) возвращает дескриптор окна.

на документация FindWindowEx функции указывает, что можно указать NULL на


следующий код отлично работает в Caculator Windows 7 в классической теме (не будет работать в Basic или Aero theme):

==================================================

IntPtr hwndFrame = FindWindowEx(hwnd, IntPtr.Zero, "CalcFrame", null); 
IntPtr hwndDialog = FindWindowEx(hwndFrame, IntPtr.Zero, "#32770", null); 
IntPtr hwndDialog2 = FindWindowEx(hwndFrame, (IntPtr)hwndDialog, "#32770", null);


IntPtr hwndThree = FindWindowEx(hwndDialog2, IntPtr.Zero, "Button", "3"); 
SendMessage((int)hwndThree, BN_CLICKED, 0, IntPtr.Zero);

IntPtr hwndPlus = FindWindowEx(hwndDialog2, IntPtr.Zero, "Button", "+");
SendMessage((int)hwndPlus, BN_CLICKED, 0, IntPtr.Zero);

IntPtr hwndOne = FindWindowEx((IntPtr)hwndDialog2, IntPtr.Zero, "Button", "1");
SendMessage((int)hwndOne, BN_CLICKED, 0, IntPtr.Zero);

IntPtr hwndEqual = FindWindowEx(hwndDialog2, IntPtr.Zero, "Button", "=");
SendMessage((int)hwndEqual, BN_CLICKED, 0, IntPtr.Zero);

я смог повторить это на Win7 Pro. Ваша проблема, вероятно, что метки на кнопках рисуются через тему калькулятора, а не в качестве подписи. Когда служба тем запущена, запуск калькулятора приведет к тому, что у него будут кнопки без подписи.

чтобы получить правильные подписи кнопок, вы должны:

  1. остановить службу тем (run net stop themes из командной строки с повышенными правами или с помощью средства администрирования служб).
  2. старт Калькулятор.

Если у вас есть калькулятор работает при остановке службы темы, вы заметите, что все его кнопки становятся пустыми.