mocodeproject Ответов: 0

Почему установка положения внешнего приложения корректно работает только с точкой останова?


Я пытаюсь переместить положение внешнего приложения, то есть экранной клавиатуры. Он работает правильно только в том случае, если я ставлю точку останова. Если я запускаю его либо из VS без точки останова, либо с помощью исполняемого файла, он не работает. Почему?

Что я уже пробовал:

[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

[DllImport("user32.dll", SetLastError = true)]
static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);

const uint SWP_NOSIZE = 0x0001;

public void SetWindowPosition(string txtAppTitle, string txtWidth, string txtHeight, string txtX, string txtY)
{
    IntPtr hWnd = FindWindow(null, txtAppTitle);

    // If found, position it.
    if (hWnd != IntPtr.Zero)
    {
        // Move the window to (txtX, txtY) without changing its size.
        int x = int.Parse(txtX);
        int y = int.Parse(txtY);
        SetWindowPos(hWnd, IntPtr.Zero, x, y, 0, 0, SWP_NOSIZE);
    }
}

private void btnOnScreenKeyboard_Click(object sender, EventArgs e)
{
    SetWindowPosition("On-Screen Keyboard", "0", "0", "155", "545");
}

mocodeproject

Я пробовал систему.Нарезание резьбы.Нить.Sleep(30); в начале метода SetWindowPosition и он, кажется, исправляет проблему, но есть ли лучший способ исправить это, а не использовать поток.Спать

Dotnet_Dotnet

сэр запуска каждого приложения в отдельном потоке

mocodeproject

Не могли бы вы более конкретно рассказать о каждом "приложении"

Richard MacCutchan

Почему вы посылаете строки вместо целочисленных значений для чисел? Вы можете узнать, почему он не работает, добавив в приложение некоторый код отладки/ведения журнала.

mocodeproject

Я добавить некоторые отладки и протоколирования кода
боол успех = setwindowpos и(hwnd элемента, указателя IntPtr.Ноль, Х, Y, ширина, высота, 0);
int err = Маршал.GetLastWin32Error();

и я получаю success = false и err=1400, что означает ERROR_INVALID_WINDOW_HANDLE = 1400 после чтения немного графический интерфейс нуждается в большем времени для загрузки перед моим методом, так что мне нужна какая-то задержка в начале моего метода любые идеи, что это лучший способ. Я пробовал систему.Нарезание резьбы.Нить.Sleep(50); и это исправило проблему, но есть ли лучший способ, чем поток.Спать.

Richard MacCutchan

Я не совсем понимаю, что вы имеете в виду. "графический интерфейс требует больше времени для загрузки"- Какой графический интерфейс вы имеете в виду?

mocodeproject

форма приложения, содержащая кнопку "btnOnScreenKeyboard", которая при нажатии вызывает метод SetWindowPosition

Richard MacCutchan

Извините, я все еще не понимаю. Эта форма уже должна быть видна, чтобы вы могли нажать на кнопку.

ZurdoDev

Я думаю, что у OP есть код, который открывает приложение или окно или что-то еще. Когда код достигает точки останова, он дает другому приложению время для открытия, чтобы код работал. Но простой запуск кода не работает, потому что другое окно еще не закончило открываться.

mocodeproject

@011111100010‬
да, именно так, и код работает идеально, когда я бросаю нить.Sleep(50) в начале метода SetWindowPosition. Но я не хочу использовать thread.sleep есть ли какое-то другое решение.

ZurdoDev

Вы можете создать функцию обратного вызова и использовать таймер для проверки каждые 100 миллисекунд или около того, чтобы увидеть, загружена ли форма. Я не уверен в коде, чтобы сделать это, но я думаю, что вы можете получить ручку к окну, а затем проверить статус.

mocodeproject

@Ричард MacCutchan
Да, форма видна, и я могу нажать на кнопку, она отлично работает, когда я использую поток.Sleep(50); но я не хочу использовать thread.sleep, потому что это просто останавливает все приложение на 50 мс, и я не хочу, чтобы это произошло, у вас есть какие-нибудь другие идеи.

Richard MacCutchan

К сожалению, нет.

ZurdoDev

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

0 Ответов