Нарушения работы DLL с файловыми отображениями после вызова функции "WindowHandle()".

 

Занимаюсь сейчас библиотекой, которая организует три пространства имён. Глобальное, терминальное и оконное.
Первые два работают без проблем. Идетификатором там являются ID процесса. Для идентификации окна использую всем известную функцию MQL4 "WindowHandle()".
Долго не мог понять почему при правильном формировании имени файлового отображения залезть в него можно было по любому имени. Ситуация необъяснимая. ТАКОГО НЕ МОЖЕТ БЫТЬ!!!

Три дня искал... Оказалось, что функция "WindowHandle()" обладает волшебными свойствами. Любое упоминание в коде приводит к неработоспособности в библиотеке. Никакие преобразования полученного дескриптора с помощью этой волшебной функции не помогают. Чего только я не пробывал... Делил, умножал, преобразовывал в разные типы... Ничего не помогало. Применил функцию Win API "GetForegroundWindow()"... И всё заработало, как положено!!! Потом заменил вызов "WindowHandle()" на константу. Подставил готовый дескриптор окна. Всё работало, как задумано! Чудеса MQL4!!!

Метаквотам удалось создать нечто, воистину, единое и неделимое!
Может они снизойдут и исправят это безобразие?...

 

Вот так тоже не работает:

GlobalVariableSet("WindowHandle", WindowHandle(Symbol(), 0)); // Пишем дескриптор в глобальную переменную.
int hWindow = GlobalVariableGet("WindowHandle"); // Читаем дескриптор из глобальной переменной.
MemoryInitWindow(hWindow, InitPostfix, 10); // Инициализация библиотеки.

А так работает:

WindowHandle(Symbol(), 0); // Применим просто так для чистоты эксперимента.
int hWindow = 0x00061536; // Присвоим константу. Дескриптор нашёл в Spy.
MemoryInitWindow(hWindow, InitPostfix, 10); // Инициализация библиотеки.
 
Zhunko:

Вот так тоже не работает:

GlobalVariableSet("WindowHandle", WindowHandle(Symbol(), 0)); // Пишем дескриптор в глобальную переменную.
int hWindow = GlobalVariableGet("WindowHandle"); // Читаем дескриптор из глобальной переменной.
MemoryInitWindow(hWindow, InitPostfix, 10); // Инициализация библиотеки.
   

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

GlobalVariableSet("WindowHandle", WindowHandle(Symbol(), 0)); // Пишем дескриптор в глобальную переменную.

Потом прочитать в другом скрипте:

int hWindow = GlobalVariableGet("WindowHandle"); // Читаем дескриптор из глобальной переменной.
MemoryInitWindow(hWindow, InitPostfix, 10); // Инициализация библиотеки.
То всё работает!
 

Сделал свою функцию аналог WindowHandle(). Не работает код с ней!!! Пробывал из моей функции передавать дескриптор окна родителя графика. Это тоже не работает. Работает только с дескриптором терминала. Но он мне не нужен. Да и все дескрипторы выше окна графика не нужны.

Что же это такое?!!! 

Явно, что дело не в самой функции и её вызовах. Почему обращение к дескрипторам окон приводит к такому результату? 

 

А можно запринтить в лог все этапы, чтобы хоть было понятно, что именно не отрабатывает - глобальные переменные терминала или функция WindowHandle? Насколько я понял, суть в том, что хэндл окна в некоторых случаях возвращается неверный?

 

Дескриптор всегда верный. Что-то портится в памяти. Может некорректно чистится после завершения потока скрипта в случаях вызова функции WindowHandle() или её аналогов.

Лог тут не поможет. Даже отладчик студии не помогает. Отладчик показывает, что всё в порядке. Обращение идёт куда положено, что нет обращения к чужой памяти. Это всё очень странно...

 

Тогда нужен тест-кейс - исходник минимальной dll с функцией, которая перестает работать, получая нормальный хендл. Судя по словам "Сделал свою функцию аналог WindowHandle(). Не работает код с ней", проблема не является специфичной для метаквотовской реализации WindowHandle.

Вы не дергаете очередь сообщений внутри dll?

 

Да. Надо собрать простой тест. Но тоже, вряд ли, кому поможет.

Проблема не в вызовах этих функций, а в том, что происходит после завершения потока скрипта в МТ4.

Очередь сообщений не трогаю. У меня её нет.

 

Это только Метаквоты смогут объяснить, если захотят разбираться. Проблема только у меня. Стало быть, не захотят... 

 

Zhunko:

Проблема только у меня. Стало быть, не захотят...

Ну зачем так сразу - не захотят.

А может нужно вначале приплатить им немного? :)

 

Только, что провёл ещё один эксперимент. Сделал в своей функции аналоге WindowHandle() получение дескриптора в отдельно потоке. И по его завершении передавал дескриптор.

Не вышло, не работает так. Прежние проблемы... 

 
Zhunko:

А так работает: 

WindowHandle(Symbol(), 0); // Применим просто так для чистоты эксперимента.
int hWindow = 0x00061536; // Присвоим константу. Дескриптор нашёл в Spy.
MemoryInitWindow(hWindow, InitPostfix, 10); // Инициализация библиотеки.

В продолжение этого эксперимента:

int hWindow = WindowHandle(Symbol(), 0); // Применим просто так для чистоты эксперимента.
hWindow = 0x00670518; // Присвоим константу. Дескриптор нашёл в Spy.
MemoryInitWindow(hWindow, InitPostfix, 10); // Инициализация библиотеки.
Так работает тоже.
Причина обращения: