Это дешево, сердито, однако нестабильно, включение каждый 5й раз сбоит примерно, отключение( "^S") через раз, причем при отключении вешает комп ещё и, это не вариант. У меня было вот так:
Код
public class DdeStartStop
{
private static string _exportMenuKey = "Экспорт данных";
private static string _stopExportMenuItem = "Остановить экспорт таблиц по &DDE";
private static string _startExportByDDEMenuItem = "Начать экспорт таблиц по &DDE";
private const UInt32 MF_BYPOSITION = 0x00000400;
[DllImport("user32.dll")]
private static extern IntPtr GetMenu(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern IntPtr GetSubMenu(IntPtr hMenu, int nPos);
[DllImport("user32.dll")]
private static extern int GetMenuItemCount(IntPtr hMenu);
[DllImport("user32.dll")]
private static extern int GetMenuString(IntPtr hMenu, uint uIDItem, StringBuilder lpString, int nMaxCount, uint uFlag);
[DllImport("user32.dll")]
private static extern uint GetMenuItemID(IntPtr hMenu, int nPos);
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("user32.dll", SetLastError = true)]
private static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
private static IntPtr[] FindQuikWindow()
{
var processes = Process.GetProcessesByName("info");
var result = new IntPtr[processes.Length];
for (int i = 0; i < processes.Length; i++)
result[i] = processes[i].MainWindowHandle;
return result;
}
private static uint FindMenuItemByPart(IntPtr menu, string name)
{
int menuItemsCount = GetMenuItemCount(menu);
for (uint menuIndex = 0; menuIndex < menuItemsCount; menuIndex++)
{
var result = new StringBuilder();
GetMenuString(menu, menuIndex, result, 1024, MF_BYPOSITION);
string buffer = result.ToString();
if (buffer.Contains(name))
{
return menuIndex;
}
}
return 0;
}
public static bool StartDDE()
{
IntPtr[] quikWindows = FindQuikWindow();
if (quikWindows.Length == 0)
return false;
foreach (var quikWindow in quikWindows)
{
try
{
IntPtr mainMenu = GetMenu(quikWindow);
int exportMenuIndex = (int)FindMenuItemByPart(mainMenu, _exportMenuKey);
IntPtr exportMenu = GetSubMenu(mainMenu, exportMenuIndex);
uint exportIndex = 6;
uint menuItem = GetMenuItemID(exportMenu, (int)exportIndex);
PostMessage(quikWindow, 0x111, (IntPtr)menuItem, (IntPtr)0);
}
catch (Exception)
{
}
}
return true;
}
public static bool StopDDE()
{
IntPtr[] quikWindows = FindQuikWindow();
if (quikWindows.Length == 0)
return false;
try
{
foreach (var quikWindow in quikWindows)
{
IntPtr mainMenu = GetMenu(quikWindow);
int exportMenuIndex = (int)FindMenuItemByPart(mainMenu, _exportMenuKey);
IntPtr exportMenu = GetSubMenu(mainMenu, exportMenuIndex);
uint exportIndex = 7;
uint menuItem = GetMenuItemID(exportMenu, (int)exportIndex);
PostMessage(quikWindow, 0x111, (IntPtr)menuItem, (IntPtr)0);
}
}
catch (Exception) {}
return true;
}
}
ЗЫ как по мне не особо и накладно хоткей нажать руками, такие выкрутысы с запуском меню через winapi до добра не доводят, лишняя сложность, лишние глюки, например какието окна выскочат в квике сообщение непонятно куда полетит
Стартовал "DDE автостарт" посредством WIN API, аналогично тому как делал Михаил Светлов и bondar. Все отлично работало. Перешел на Windows 10, VS 2015, и Quik 7.4 (демо версия), теперь GetMenu(HdlQuikMainWindow) возвращает 0. Не могу понять то ли в этой версии Quik основное меню как то сделано по другому, так что оно теперь и не меню вовсе, то ли Windows 10 c VS 2015 не дают получить hndl меню. Хотя это тоже маловероятно - все остальные API функции, которые использую для перебора окон и т.д. работают нормально. Сталкивался ли кто либо с проблемой GetMenu(HdlQuikMainWi ndow)=0 для Quik версии 7.4
Может разработчики подскажут, в версии 7.4 основное меню какое-нибудь непростое, динамически формируемое, всплывающее, может просто кнопки замаскированная под меню и т.д.
И еще, может разработчики подскажут где взять работающий Quik (демо) версии 6. Хочется разобраться почему GetMenu возвращает 0 - дело в версии Quik или в системе?
V. Y. написал: И еще, может разработчики подскажут где взять работающий Quik (демо) версии 6. Хочется разобраться почему GetMenu возвращает 0 - дело в версии Quik или в системе?
Пользователю - еще раз спасибо за ссылку на FTP архив. Изучил методом "тыка и исключений" 6 и 7 версии Quik. Вывод совершенно непонятный. Все 7 версии, включая 7.4 отлично работают, в том смысле что API функция GetMenu находит handle меню по handle главного окна Quik, - но только тогда, когда тема оформления интерфейса Quik - стандартная. Т.е. если в меню Quik выбрать Система ->Настройки -> Основные настройки -> Программа -> Оформление интерфейса установить "Темная тема", то GetMenu перестает видеть меню Quik - djpdhfoftn 0. А если установить "Стандартная тема", то все прекрасно работает - GetMenu возвращает handle меню. В чем может быть, если честно, идей пока нет. Ведь если меню перекрашивают в темный цвет - оно не перестает быть меню, и GetMenu все равно должна его находить. Думаю поискать какую нибудь альтернативу GetMenu, может SendMessage c какими нибудь хитрыми параметрами. Дайте знать если у кого нибуть есть идеи как получить handle меню независимо от того как оно раскрашено.
V. Y. написал: Вывод совершенно непонятный. Все 7 версии, включая 7.4 отлично работают, в том смысле что API функция GetMenu находит handle меню по handle главного окна Quik, - но только тогда, когда тема оформления интерфейса Quik - стандартная.
Что ж вы молчали, что используете тёмную тему. Тогда всё как раз понятно: QUIK в тёмной теме всё рисует своими средствами, потому меню в смысле WinAPI там нет. Вы автоматизируете тот терминал, на котором сами же и работаете?
Начал было автоматизировать (версию 6.5) - потом забросил, времени не было, "не до глупостей" :)))) Сейчас решил вернуться, - вижу новая версия появилась, такая красивая, "темненькая", а тут такая "засада". Мне и в голову не могло прийти, что в темной теме меню динамически рисуется. Неделю бился, пока не догадался написать на форум. Что теперь делать - не ясно. А вдруг в следующих версиях разработчикам придет в голову мысль рисовать и "светлую" тему. Тогда идея автоматизации Quik посредством "шастанья по меню" - вообще не пройдет. А других способов, кроме SendKey, который крайне нежелателен из за своей нестабильности и непредсказуемости, вроде как и нет. Swerg - натолкните на мысль- в каком направлении копать, что бы можно было работать с меню и в темной и в светлой теме. Вроде должно сработать SendMessage c параметром MN_GETHMENU, но тоже пока не получается.
Я хоть и не swerg, но посоветую вам пользоваться только документированными возможностями. Использование любых других фич, особенностей и трюков ведет к написанию нестабильно работающих программ, а также к полной потере всех наработок с выходом новых версий терминала, которые появляются довольно часто.
Если у вас есть лишнее свободное время, лучше его потратить на общение с близкими вам людьми.
Совершенно с вами согласен, по всем пунктам. А если хотя бы намекнули на документированную возможность старта из стороннего приложения экспорт конкретной таблицы Quik - обещаю забыть об API и все освободившиеся время посвятить исключительно близким, включая любимого кота, ну или хотя бы потратить его на борьбу за мир во всем мире ))). Я серьезно, если знаете подскажите.