Прочесть таблицу новости через LUA

Страницы: 1 2 След.
RSS
Прочесть таблицу новости через LUA
 
Друзья, подскажите пожалуйста можно ли как-то прочитать таблицу новостей QUIK через LUA ?
 
Никак
 
Цитата
null написал:
Друзья, подскажите пожалуйста можно ли как-то прочитать таблицу новостей QUIK через LUA ?
Можно через библиотеку w32.dll функциями FindWindow и FindWindowEx рекурсивно перебрать все дочерние открытые окна в Quik и найти окно новостей по имени класса «InfoNews». Оттуда уже из его дочернего окна списка вытащить новости.
 
Цитата
Suntor написал:
Цитата
null   написал:
Друзья, подскажите пожалуйста можно ли как-то прочитать таблицу новостей QUIK через LUA ?
Можно через библиотеку  w32.dll  функциями FindWindow и FindWindowEx рекурсивно перебрать все дочерние открытые окна в Quik и найти окно новостей по имени класса «InfoNews». Оттуда уже из его дочернего окна списка вытащить новости.
Спасибо  получилось.  Может кому пригодится список хендлов их очередность для чтения. Стрелочка показывает родителя.
Код
0015085A InfoClass - главное окно квика
^
00010890 MDIClient
^
000108AE HostWindow
^
000108A4 InfoNews
^
000108A6 MultiList - Список новостей(нужно кликнуть по нужной новости)(родитель InfoNews)
000108AC RichEdit20A - Текст новости(родитель InfoNews)
 
PS. Не использовал LUA и костыль в виде библиотеки w32. Иcпользовал C++ т.к. основной функционал у меня написан на LUA C.
 
Цитата
null написал:
Может кому пригодится список хендлов
«хендлы» — это указатели, список их значений смысла не имеет, они всегда разные... при повторном запуске Quik, повторном создании окна и т.д... привязываться можно только к строковым именам окон и их классов...
 
Цитата
Suntor написал:
Цитата
null   написал:
Может кому пригодится список хендлов
«хендлы» — это указатели, список их значений смысла не имеет, они всегда разные... при повторном запуске Quik, повторном создании окна и т.д... привязываться можно только к строковым именам окон и их классов...
Кстати может знаете как из MultiList получить список строк? Чтобы прочесть новость, в мультилисте надо даблкликнуть по новости, тогда она только появится RichEdit20A. Что-то мне костыльная затея по считыванию числа новостей из заголовка и вычисление высоты строки делением высоты контейнера на количество новостей, и эмуляцию координат дабл клика не очень нравится(и не факт, что будет работать, слишком дробная высота строки получается). Может у списка есть какие-то служебные сообщения.
Код
            const size_t tlen = SendMessage(hNews, WM_GETTEXTLENGTH, NULL, NULL);
            wchar_t* title = new wchar_t[tlen + 1];
            SendMessage(hNews, WM_GETTEXT, tlen + 1, LPARAM(title));
            const HWND hMulti = FindWindowEx(hNews, nullptr, L"MultiList", nullptr);
            const LPRECT rect = new tagRECT();
            GetWindowRect(hMulti, rect);
            std::cout << (rect->bottom - rect->top) << std::endl;
 
Цитата
null написал:
Кстати может знаете как из MultiList получить список строк?
Это, по-видимому, какой-то самописный класс со своими закрытыми сообщениями. Возможно, к нему есть возможность сделать запрос, но нужно знать коды этих самых сообщений. Можно конечно повозиться с Spy++ и попытаться отследить коды сообщений, но лучше чтобы сама тех. поддежка Quik их предоставила.
 
Цитата
Suntor написал:
Цитата
null   написал:
Кстати может знаете как из MultiList получить список строк?
Это, по-видимому, какой-то самописный класс со своими закрытыми сообщениями. Возможно, к нему есть возможность сделать запрос, но нужно знать коды этих самых сообщений. Можно конечно повозиться с Spy++ и попытаться отследить коды сообщений, но лучше чтобы сама тех. поддежка Quik их предоставила.
SPY++ не ловит. Пробовал. Да это какой-то самописный класс. Поддержка наверное не даст коды сообщений. :sad:
 
Цитата
null написал:
SPY++ не ловит. Пробовал. Да это какой-то самописный класс. Поддержка наверное не даст коды сообщений.
У меня ловит... разрядность версии проверьте.
 
Цитата
Suntor написал:
Цитата
null   написал:
SPY++ не ловит. Пробовал. Да это какой-то самописный класс. Поддержка наверное не даст коды сообщений.
У меня ловит... разрядность версии проверьте.
Он ловит только стандартные.
Код
<000001> 00090A5E S WM_NCPAINT hrgn:00000001
<000002> 00090A5E R WM_NCPAINT
<000003> 00090A5E S WM_ERASEBKGND hdc:E60115D0
<000004> 00090A5E R WM_ERASEBKGND fErased:True
<000005> 00090A5E S WM_PAINT hdc:00000000
<000006> 00090A5E R WM_PAINT
<000007> 00090A5E S WM_INPUTLANGCHANGE charset:0 hkl:04090409
<000008> 00090A5E R WM_INPUTLANGCHANGE
<000009> 00090A5E S WM_IME_SETCONTEXT fSet:1 iShow:C000000F
<000010> 00090A5E R WM_IME_SETCONTEXT
<000011> 00090A5E S WM_SETFOCUS hwndLoseFocus:00050AEE
<000012> 00090A5E R WM_SETFOCUS
<000013> 00090A5E S WM_KILLFOCUS hwndGetFocus:00200A16
<000014> 00090A5E R WM_KILLFOCUS
<000015> 00090A5E S WM_IME_SETCONTEXT fSet:0 iShow:C000000F
<000016> 00090A5E R WM_IME_SETCONTEXT
<000017> 00090A5E S WM_IME_SETCONTEXT fSet:1 iShow:C000000F
<000018> 00090A5E R WM_IME_SETCONTEXT
<000019> 00090A5E S WM_SETFOCUS hwndLoseFocus:00050AEE
<000020> 00090A5E R WM_SETFOCUS
<000021> 00090A5E S WM_NCHITTEST xPos:371 yPos:235
<000022> 00090A5E R WM_NCHITTEST nHittest:HTCLIENT
<000023> 00090A5E S WM_SETCURSOR hwnd:00090A5E nHittest:HTCLIENT wMouseMsg:WM_MOUSEMOVE
<000024> 00090A5E R WM_SETCURSOR fHaltProcessing:False
<000025> 00090A5E P WM_MOUSEMOVE fwKeys:0000 xPos:363 yPos:92
<000026> 00090A5E S WM_NCHITTEST xPos:371 yPos:235
<000027> 00090A5E R WM_NCHITTEST nHittest:HTCLIENT
<000028> 00090A5E S WM_MOUSEACTIVATE hwndTopLevel:00200A16 nHittest:HTCLIENT uMsg:WM_LBUTTONDOWN
<000029> 00090A5E R WM_MOUSEACTIVATE fuActivate:MA_ACTIVATE
<000030> 00090A5E S WM_SETCURSOR hwnd:00090A5E nHittest:HTCLIENT wMouseMsg:WM_LBUTTONDOWN
<000031> 00090A5E R WM_SETCURSOR fHaltProcessing:False
<000032> 00090A5E P WM_LBUTTONDOWN fwKeys:MK_LBUTTON xPos:363 yPos:92
<000033> 00090A5E S WM_KILLFOCUS hwndGetFocus:00050AEE
<000034> 00090A5E R WM_KILLFOCUS
<000035> 00090A5E S WM_IME_SETCONTEXT fSet:0 iShow:C000000F
<000036> 00090A5E R WM_IME_SETCONTEXT
<000037> 00090A5E S WM_IME_SETCONTEXT fSet:1 iShow:C000000F
<000038> 00090A5E R WM_IME_SETCONTEXT
<000039> 00090A5E S WM_SETFOCUS hwndLoseFocus:00050AEE
<000040> 00090A5E R WM_SETFOCUS
<000041> 00090A5E S WM_NCHITTEST xPos:371 yPos:235
<000042> 00090A5E R WM_NCHITTEST nHittest:HTCLIENT
<000043> 00090A5E S WM_SETCURSOR hwnd:00090A5E nHittest:HTCLIENT wMouseMsg:WM_LBUTTONUP
<000044> 00090A5E R WM_SETCURSOR fHaltProcessing:False
<000045> 00090A5E P WM_LBUTTONUP fwKeys:0000 xPos:363 yPos:92
<000046> 00090A5E S WM_NCHITTEST xPos:371 yPos:235
<000047> 00090A5E R WM_NCHITTEST nHittest:HTCLIENT
<000048> 00090A5E S WM_MOUSEACTIVATE hwndTopLevel:00200A16 nHittest:HTCLIENT uMsg:WM_LBUTTONDOWN
<000049> 00090A5E R WM_MOUSEACTIVATE fuActivate:MA_ACTIVATE
<000050> 00090A5E S WM_SETCURSOR hwnd:00090A5E nHittest:HTCLIENT wMouseMsg:WM_LBUTTONDOWN
<000051> 00090A5E R WM_SETCURSOR fHaltProcessing:False
<000052> 00090A5E P WM_LBUTTONDBLCLK fwKeys:MK_LBUTTON xPos:363 yPos:92
<000053> 00090A5E S WM_NCHITTEST xPos:371 yPos:235
<000054> 00090A5E R WM_NCHITTEST nHittest:HTCLIENT
<000055> 00090A5E S WM_SETCURSOR hwnd:00090A5E nHittest:HTCLIENT wMouseMsg:WM_LBUTTONUP
<000056> 00090A5E R WM_SETCURSOR fHaltProcessing:False
<000057> 00090A5E P WM_LBUTTONUP fwKeys:0000 xPos:363 yPos:92
<000058> 00090A5E S WM_KILLFOCUS hwndGetFocus:(не определено)
<000059> 00090A5E R WM_KILLFOCUS
<000060> 00090A5E S WM_IME_SETCONTEXT fSet:0 iShow:C000000F
<000061> 00090A5E S WM_IME_NOTIFY dwCommand:IMN_CLOSESTATUSWINDOW dwCommand:00000001 dwData:00000000
<000062> 00090A5E R WM_IME_NOTIFY
<000063> 00090A5E R WM_IME_SETCONTEXT
<000064> 00090A5E P WM_MOUSELEAVE
<000065> 00090A5E P WM_PAINT hdc:00000000
<000066> 00090A5E S WM_NCHITTEST xPos:369 yPos:218
<000067> 00090A5E R WM_NCHITTEST nHittest:HTCLIENT
<000068> 00090A5E S WM_SETCURSOR hwnd:00090A5E nHittest:HTCLIENT wMouseMsg:WM_MOUSEMOVE
<000069> 00090A5E R WM_SETCURSOR fHaltProcessing:False
<000070> 00090A5E P WM_MOUSEMOVE fwKeys:0000 xPos:361 yPos:75
<000071> 00090A5E S WM_NCHITTEST xPos:392 yPos:188
<000072> 00090A5E R WM_NCHITTEST nHittest:HTCLIENT
<000073> 00090A5E S WM_SETCURSOR hwnd:00090A5E nHittest:HTCLIENT wMouseMsg:WM_MOUSEMOVE
<000074> 00090A5E R WM_SETCURSOR fHaltProcessing:False
<000075> 00090A5E P WM_MOUSEMOVE fwKeys:0000 xPos:384 yPos:45
<000076> 00090A5E S WM_NCHITTEST xPos:392 yPos:187
<000077> 00090A5E R WM_NCHITTEST nHittest:HTCLIENT
<000078> 00090A5E S WM_SETCURSOR hwnd:00090A5E nHittest:HTCLIENT wMouseMsg:WM_MOUSEMOVE
<000079> 00090A5E R WM_SETCURSOR fHaltProcessing:False
<000080> 00090A5E P WM_MOUSEMOVE fwKeys:MK_LBUTTON xPos:384 yPos:44
<000081> 00090A5E S WM_NCHITTEST xPos:392 yPos:187
<000082> 00090A5E R WM_NCHITTEST nHittest:HTCLIENT
<000083> 00090A5E S WM_MOUSEACTIVATE hwndTopLevel:00200A16 nHittest:HTCLIENT uMsg:WM_LBUTTONDOWN
<000084> 00090A5E R WM_MOUSEACTIVATE fuActivate:MA_ACTIVATE
<000085> 00090A5E S WM_IME_SETCONTEXT fSet:1 iShow:C000000F
<000086> 00090A5E S WM_IME_NOTIFY dwCommand:IMN_OPENSTATUSWINDOW dwCommand:00000002 dwData:00000000
<000087> 00090A5E R WM_IME_NOTIFY
<000088> 00090A5E R WM_IME_SETCONTEXT
<000089> 00090A5E S WM_SETFOCUS hwndLoseFocus:(не определено)
<000090> 00090A5E R WM_SETFOCUS
<000091> 00090A5E S WM_KILLFOCUS hwndGetFocus:00200A16
<000092> 00090A5E R WM_KILLFOCUS
<000093> 00090A5E S WM_IME_SETCONTEXT fSet:0 iShow:C000000F
<000094> 00090A5E R WM_IME_SETCONTEXT
<000095> 00090A5E S WM_IME_SETCONTEXT fSet:1 iShow:C000000F
<000096> 00090A5E R WM_IME_SETCONTEXT
<000097> 00090A5E S WM_SETFOCUS hwndLoseFocus:00050AEE
<000098> 00090A5E R WM_SETFOCUS
<000099> 00090A5E S WM_SETCURSOR hwnd:00090A5E nHittest:HTCLIENT wMouseMsg:WM_LBUTTONDOWN
<000100> 00090A5E R WM_SETCURSOR fHaltProcessing:False
<000101> 00090A5E P WM_LBUTTONDOWN fwKeys:MK_LBUTTON xPos:384 yPos:44
<000102> 00090A5E S WM_KILLFOCUS hwndGetFocus:00050AEE
<000103> 00090A5E R WM_KILLFOCUS
<000104> 00090A5E S WM_IME_SETCONTEXT fSet:0 iShow:C000000F
<000105> 00090A5E R WM_IME_SETCONTEXT
<000106> 00090A5E S WM_IME_SETCONTEXT fSet:1 iShow:C000000F
<000107> 00090A5E R WM_IME_SETCONTEXT
<000108> 00090A5E S WM_SETFOCUS hwndLoseFocus:00050AEE
<000109> 00090A5E R WM_SETFOCUS
<000110> 00090A5E S WM_NCHITTEST xPos:392 yPos:187
<000111> 00090A5E R WM_NCHITTEST nHittest:HTCLIENT
<000112> 00090A5E S WM_SETCURSOR hwnd:00090A5E nHittest:HTCLIENT wMouseMsg:WM_LBUTTONUP
<000113> 00090A5E R WM_SETCURSOR fHaltProcessing:False
<000114> 00090A5E P WM_LBUTTONUP fwKeys:0000 xPos:384 yPos:44
<000115> 00090A5E S WM_NCHITTEST xPos:392 yPos:187
<000116> 00090A5E R WM_NCHITTEST nHittest:HTCLIENT
<000117> 00090A5E S WM_MOUSEACTIVATE hwndTopLevel:00200A16 nHittest:HTCLIENT uMsg:WM_LBUTTONDOWN
<000118> 00090A5E R WM_MOUSEACTIVATE fuActivate:MA_ACTIVATE
<000119> 00090A5E S WM_SETCURSOR hwnd:00090A5E nHittest:HTCLIENT wMouseMsg:WM_LBUTTONDOWN
<000120> 00090A5E R WM_SETCURSOR fHaltProcessing:False
<000121> 00090A5E P WM_LBUTTONDBLCLK fwKeys:MK_LBUTTON xPos:384 yPos:44
<000122> 00090A5E S WM_NCHITTEST xPos:392 yPos:187
<000123> 00090A5E R WM_NCHITTEST nHittest:HTCLIENT
<000124> 00090A5E S WM_SETCURSOR hwnd:00090A5E nHittest:HTCLIENT wMouseMsg:WM_LBUTTONUP
<000125> 00090A5E R WM_SETCURSOR fHaltProcessing:False
<000126> 00090A5E P WM_LBUTTONUP fwKeys:0000 xPos:384 yPos:44
<000127> 00090A5E S WM_NCHITTEST xPos:392 yPos:187
<000128> 00090A5E R WM_NCHITTEST nHittest:HTCLIENT
<000129> 00090A5E S WM_SETCURSOR hwnd:00090A5E nHittest:HTCLIENT wMouseMsg:WM_MOUSEMOVE
<000130> 00090A5E R WM_SETCURSOR fHaltProcessing:False
<000131> 00090A5E P WM_MOUSEMOVE fwKeys:0000 xPos:384 yPos:44
<000132> 00090A5E S WM_NCHITTEST xPos:392 yPos:187
<000133> 00090A5E R WM_NCHITTEST nHittest:HTCLIENT
<000134> 00090A5E S WM_MOUSEACTIVATE hwndTopLevel:00200A16 nHittest:HTCLIENT uMsg:WM_LBUTTONDOWN
<000135> 00090A5E R WM_MOUSEACTIVATE fuActivate:MA_ACTIVATE
<000136> 00090A5E S WM_SETCURSOR hwnd:00090A5E nHittest:HTCLIENT wMouseMsg:WM_LBUTTONDOWN
<000137> 00090A5E R WM_SETCURSOR fHaltProcessing:False
<000138> 00090A5E P WM_LBUTTONDOWN fwKeys:MK_LBUTTON xPos:384 yPos:44
<000139> 00090A5E S WM_KILLFOCUS hwndGetFocus:00050AEE
<000140> 00090A5E R WM_KILLFOCUS
<000141> 00090A5E S WM_IME_SETCONTEXT fSet:0 iShow:C000000F
<000142> 00090A5E R WM_IME_SETCONTEXT
<000143> 00090A5E S WM_IME_SETCONTEXT fSet:1 iShow:C000000F
<000144> 00090A5E R WM_IME_SETCONTEXT
<000145> 00090A5E S WM_SETFOCUS hwndLoseFocus:00050AEE
<000146> 00090A5E R WM_SETFOCUS
<000147> 00090A5E S WM_NCHITTEST xPos:392 yPos:187
<000148> 00090A5E R WM_NCHITTEST nHittest:HTCLIENT
<000149> 00090A5E S WM_SETCURSOR hwnd:00090A5E nHittest:HTCLIENT wMouseMsg:WM_LBUTTONUP
<000150> 00090A5E R WM_SETCURSOR fHaltProcessing:False
<000151> 00090A5E P WM_LBUTTONUP fwKeys:0000 xPos:384 yPos:44
<000152> 00090A5E S WM_NCHITTEST xPos:392 yPos:187
<000153> 00090A5E R WM_NCHITTEST nHittest:HTCLIENT
<000154> 00090A5E S WM_MOUSEACTIVATE hwndTopLevel:00200A16 nHittest:HTCLIENT uMsg:WM_LBUTTONDOWN
<000155> 00090A5E R WM_MOUSEACTIVATE fuActivate:MA_ACTIVATE
<000156> 00090A5E S WM_SETCURSOR hwnd:00090A5E nHittest:HTCLIENT wMouseMsg:WM_LBUTTONDOWN
<000157> 00090A5E R WM_SETCURSOR fHaltProcessing:False
<000158> 00090A5E P WM_LBUTTONDBLCLK fwKeys:MK_LBUTTON xPos:384 yPos:44
<000159> 00090A5E S WM_NCHITTEST xPos:392 yPos:187
<000160> 00090A5E R WM_NCHITTEST nHittest:HTCLIENT
<000161> 00090A5E S WM_SETCURSOR hwnd:00090A5E nHittest:HTCLIENT wMouseMsg:WM_LBUTTONUP
<000162> 00090A5E R WM_SETCURSOR fHaltProcessing:False
<000163> 00090A5E P WM_LBUTTONUP fwKeys:0000 xPos:384 yPos:44
<000164> 00090A5E S WM_NCHITTEST xPos:392 yPos:187
<000165> 00090A5E R WM_NCHITTEST nHittest:HTCLIENT
<000166> 00090A5E S WM_SETCURSOR hwnd:00090A5E nHittest:HTCLIENT wMouseMsg:WM_MOUSEMOVE
<000167> 00090A5E R WM_SETCURSOR fHaltProcessing:False
<000168> 00090A5E P WM_MOUSEMOVE fwKeys:0000 xPos:384 yPos:44
<000169> 00090A5E S WM_NCHITTEST xPos:438 yPos:384
<000170> 00090A5E R WM_NCHITTEST nHittest:HTCLIENT
<000171> 00090A5E S WM_SETCURSOR hwnd:00090A5E nHittest:HTCLIENT wMouseMsg:WM_MOUSEMOVE
<000172> 00090A5E R WM_SETCURSOR fHaltProcessing:False
<000173> 00090A5E P WM_MOUSEMOVE fwKeys:0000 xPos:430 yPos:241
<000174> 00090A5E S WM_NCHITTEST xPos:438 yPos:385
<000175> 00090A5E R WM_NCHITTEST nHittest:HTCLIENT
<000176> 00090A5E S WM_SETCURSOR hwnd:00090A5E nHittest:HTCLIENT wMouseMsg:WM_MOUSEMOVE
<000177> 00090A5E R WM_SETCURSOR fHaltProcessing:False
<000178> 00090A5E P WM_MOUSEMOVE fwKeys:0000 xPos:430 yPos:242
<000179> 00090A5E S WM_NCHITTEST xPos:438 yPos:385
<000180> 00090A5E R WM_NCHITTEST nHittest:HTCLIENT
<000181> 00090A5E S WM_MOUSEACTIVATE hwndTopLevel:00200A16 nHittest:HTCLIENT uMsg:WM_LBUTTONDOWN
<000182> 00090A5E R WM_MOUSEACTIVATE fuActivate:MA_ACTIVATE
<000183> 00090A5E S WM_SETCURSOR hwnd:00090A5E nHittest:HTCLIENT wMouseMsg:WM_LBUTTONDOWN
<000184> 00090A5E R WM_SETCURSOR fHaltProcessing:False
<000185> 00090A5E P WM_LBUTTONDOWN fwKeys:MK_LBUTTON xPos:430 yPos:242
<000186> 00090A5E S WM_KILLFOCUS hwndGetFocus:00050AEE
<000187> 00090A5E R WM_KILLFOCUS
<000188> 00090A5E S WM_IME_SETCONTEXT fSet:0 iShow:C000000F
<000189> 00090A5E R WM_IME_SETCONTEXT
<000190> 00090A5E S WM_IME_SETCONTEXT fSet:1 iShow:C000000F
<000191> 00090A5E R WM_IME_SETCONTEXT
<000192> 00090A5E S WM_SETFOCUS hwndLoseFocus:00050AEE
<000193> 00090A5E R WM_SETFOCUS
<000194> 00090A5E S WM_NCHITTEST xPos:438 yPos:385
<000195> 00090A5E R WM_NCHITTEST nHittest:HTCLIENT
<000196> 00090A5E S WM_SETCURSOR hwnd:00090A5E nHittest:HTCLIENT wMouseMsg:WM_LBUTTONUP
<000197> 00090A5E R WM_SETCURSOR fHaltProcessing:False
<000198> 00090A5E P WM_LBUTTONUP fwKeys:0000 xPos:430 yPos:242
<000199> 00090A5E S WM_NCHITTEST xPos:438 yPos:385
<000200> 00090A5E R WM_NCHITTEST nHittest:HTCLIENT
<000201> 00090A5E S WM_MOUSEACTIVATE hwndTopLevel:00200A16 nHittest:HTCLIENT uMsg:WM_LBUTTONDOWN
<000202> 00090A5E R WM_MOUSEACTIVATE fuActivate:MA_ACTIVATE
<000203> 00090A5E S WM_SETCURSOR hwnd:00090A5E nHittest:HTCLIENT wMouseMsg:WM_LBUTTONDOWN
<000204> 00090A5E R WM_SETCURSOR fHaltProcessing:False
<000205> 00090A5E P WM_LBUTTONDBLCLK fwKeys:MK_LBUTTON xPos:430 yPos:242
<000206> 00090A5E S WM_NCHITTEST xPos:438 yPos:385
<000207> 00090A5E R WM_NCHITTEST nHittest:HTCLIENT
<000208> 00090A5E S WM_SETCURSOR hwnd:00090A5E nHittest:HTCLIENT wMouseMsg:WM_LBUTTONUP
<000209> 00090A5E R WM_SETCURSOR fHaltProcessing:False
<000210> 00090A5E P WM_LBUTTONUP fwKeys:0000 xPos:430 yPos:242
<000211> 00090A5E S WM_NCHITTEST xPos:452 yPos:345
<000212> 00090A5E R WM_NCHITTEST nHittest:HTCLIENT
<000213> 00090A5E S WM_SETCURSOR hwnd:00090A5E nHittest:HTCLIENT wMouseMsg:WM_MOUSEMOVE
<000214> 00090A5E R WM_SETCURSOR fHaltProcessing:False
<000215> 00090A5E P WM_MOUSEMOVE fwKeys:0000 xPos:444 yPos:202
<000216> 00090A5E S WM_NCHITTEST xPos:519 yPos:322
<000217> 00090A5E R WM_NCHITTEST nHittest:HTCLIENT
<000218> 00090A5E S WM_SETCURSOR hwnd:00090A5E nHittest:HTCLIENT wMouseMsg:WM_MOUSEMOVE
<000219> 00090A5E R WM_SETCURSOR fHaltProcessing:False
<000220> 00090A5E P WM_MOUSEMOVE fwKeys:0000 xPos:511 yPos:179
<000221> 00090A5E S WM_NCHITTEST xPos:550 yPos:327
<000222> 00090A5E R WM_NCHITTEST nHittest:HTCLIENT
<000223> 00090A5E P WM_MOUSEWHEEL fwKeys:0000 zDelta:-720 xPos:550 yPos:327
<000224> 00090A5E S WM_STYLECHANGING wStyleType:GWL_EXSTYLE | GWL_STYLE lpss:007FED84
<000225> 00090A5E R WM_STYLECHANGING
<000226> 00090A5E S WM_STYLECHANGED wStyleType:GWL_EXSTYLE | GWL_STYLE lpss:007FED84
<000227> 00090A5E R WM_STYLECHANGED
<000228> 00090A5E S WM_STYLECHANGING wStyleType:GWL_EXSTYLE | GWL_STYLE lpss:007FED84
<000229> 00090A5E R WM_STYLECHANGING
<000230> 00090A5E S WM_STYLECHANGED wStyleType:GWL_EXSTYLE | GWL_STYLE lpss:007FED84
<000231> 00090A5E R WM_STYLECHANGED
<000232> 00090A5E S WM_STYLECHANGING wStyleType:GWL_EXSTYLE | GWL_STYLE lpss:007FED84
<000233> 00090A5E R WM_STYLECHANGING
<000234> 00090A5E S WM_STYLECHANGED wStyleType:GWL_EXSTYLE | GWL_STYLE lpss:007FED84
<000235> 00090A5E R WM_STYLECHANGED
<000236> 00090A5E S WM_NCHITTEST xPos:1113 yPos:337
<000237> 00090A5E R WM_NCHITTEST nHittest:HTCLIENT
<000238> 00090A5E S WM_SETCURSOR hwnd:00090A5E nHittest:HTCLIENT wMouseMsg:WM_MOUSEMOVE
<000239> 00090A5E R WM_SETCURSOR fHaltProcessing:False
<000240> 00090A5E P WM_MOUSEMOVE fwKeys:0000 xPos:1105 yPos:194
<000241> 00090A5E S WM_NCHITTEST xPos:1023 yPos:284
<000242> 00090A5E R WM_NCHITTEST nHittest:HTCLIENT
<000243> 00090A5E S WM_SETCURSOR hwnd:00090A5E nHittest:HTCLIENT wMouseMsg:WM_MOUSEMOVE
<000244> 00090A5E R WM_SETCURSOR fHaltProcessing:False
<000245> 00090A5E P WM_MOUSEMOVE fwKeys:0000 xPos:1015 yPos:141
<000246> 00090A5E S WM_NCHITTEST xPos:1023 yPos:284
<000247> 00090A5E R WM_NCHITTEST nHittest:HTCLIENT
<000248> 00090A5E S WM_MOUSEACTIVATE hwndTopLevel:00200A16 nHittest:HTCLIENT uMsg:WM_LBUTTONDOWN
<000249> 00090A5E R WM_MOUSEACTIVATE fuActivate:MA_ACTIVATE
<000250> 00090A5E S WM_SETCURSOR hwnd:00090A5E nHittest:HTCLIENT wMouseMsg:WM_LBUTTONDOWN
<000251> 00090A5E R WM_SETCURSOR fHaltProcessing:False
<000252> 00090A5E P WM_LBUTTONDOWN fwKeys:MK_LBUTTON xPos:1015 yPos:141
<000253> 00090A5E S WM_KILLFOCUS hwndGetFocus:00050AEE
<000254> 00090A5E R WM_KILLFOCUS
<000255> 00090A5E S WM_IME_SETCONTEXT fSet:0 iShow:C000000F
<000256> 00090A5E R WM_IME_SETCONTEXT
<000257> 00090A5E S WM_IME_SETCONTEXT fSet:1 iShow:C000000F
<000258> 00090A5E R WM_IME_SETCONTEXT
<000259> 00090A5E S WM_SETFOCUS hwndLoseFocus:00050AEE
<000260> 00090A5E R WM_SETFOCUS
<000261> 00090A5E S WM_NCHITTEST xPos:1022 yPos:283
<000262> 00090A5E R WM_NCHITTEST nHittest:HTCLIENT
<000263> 00090A5E S WM_SETCURSOR hwnd:00090A5E nHittest:HTCLIENT wMouseMsg:WM_MOUSEMOVE
<000264> 00090A5E R WM_SETCURSOR fHaltProcessing:False
<000265> 00090A5E P WM_MOUSEMOVE fwKeys:MK_LBUTTON xPos:1014 yPos:140
<000266> 00090A5E S WM_NCHITTEST xPos:1022 yPos:283
<000267> 00090A5E R WM_NCHITTEST nHittest:HTCLIENT
<000268> 00090A5E S WM_SETCURSOR hwnd:00090A5E nHittest:HTCLIENT wMouseMsg:WM_LBUTTONUP
<000269> 00090A5E R WM_SETCURSOR fHaltProcessing:False
<000270> 00090A5E P WM_LBUTTONUP fwKeys:0000 xPos:1014 yPos:140
<000271> 00090A5E S WM_NCHITTEST xPos:1130 yPos:347
<000272> 00090A5E R WM_NCHITTEST nHittest:HTCLIENT
<000273> 00090A5E P WM_MOUSEWHEEL fwKeys:0000 zDelta:-120 xPos:1130 yPos:347
<000274> 00090A5E S WM_STYLECHANGING wStyleType:GWL_EXSTYLE | GWL_STYLE lpss:007FED84
<000275> 00090A5E R WM_STYLECHANGING
<000276> 00090A5E S WM_STYLECHANGED wStyleType:GWL_EXSTYLE | GWL_STYLE lpss:007FED84
<000277> 00090A5E R WM_STYLECHANGED
<000278> 00090A5E S WM_STYLECHANGING wStyleType:GWL_EXSTYLE | GWL_STYLE lpss:007FED84
<000279> 00090A5E R WM_STYLECHANGING
<000280> 00090A5E S WM_STYLECHANGED wStyleType:GWL_EXSTYLE | GWL_STYLE lpss:007FED84
<000281> 00090A5E R WM_STYLECHANGED
<000282> 00090A5E S WM_STYLECHANGING wStyleType:GWL_EXSTYLE | GWL_STYLE lpss:007FED84
<000283> 00090A5E R WM_STYLECHANGING
<000284> 00090A5E S WM_STYLECHANGED wStyleType:GWL_EXSTYLE | GWL_STYLE lpss:007FED84
<000285> 00090A5E R WM_STYLECHANGED
<000286> 00090A5E S WM_NCHITTEST xPos:1131 yPos:348
<000287> 00090A5E R WM_NCHITTEST nHittest:HTCLIENT
<000288> 00090A5E S WM_SETCURSOR hwnd:00090A5E nHittest:HTCLIENT wMouseMsg:WM_MOUSEMOVE
<000289> 00090A5E R WM_SETCURSOR fHaltProcessing:False
<000290> 00090A5E P WM_MOUSEMOVE fwKeys:0000 xPos:1123 yPos:205
<000291> 00090A5E S WM_NCHITTEST xPos:1793 yPos:169
<000292> 00090A5E R WM_NCHITTEST nHittest:HTVSCROLL
<000293> 00090A5E S WM_SETCURSOR hwnd:00090A5E nHittest:HTVSCROLL wMouseMsg:WM_MOUSEMOVE
<000294> 00090A5E R WM_SETCURSOR fHaltProcessing:False
<000295> 00090A5E P WM_NCMOUSEMOVE nHittest:HTVSCROLL xPos:1793 yPos:169
<000296> 00090A5E P WM_NCMOUSELEAVE
<000297> 00090A5E S WM_NCHITTEST xPos:1793 yPos:170
<000298> 00090A5E R WM_NCHITTEST nHittest:HTVSCROLL
<000299> 00090A5E S WM_SETCURSOR hwnd:00090A5E nHittest:HTVSCROLL wMouseMsg:WM_MOUSEMOVE
<000300> 00090A5E R WM_SETCURSOR fHaltProcessing:False
<000301> 00090A5E P WM_NCMOUSEMOVE nHittest:HTVSCROLL xPos:1793 yPos:170
<000302> 00090A5E P WM_NCMOUSELEAVE
<000303> 00090A5E S WM_NCHITTEST xPos:1793 yPos:170
<000304> 00090A5E R WM_NCHITTEST nHittest:HTVSCROLL
<000305> 00090A5E S WM_MOUSEACTIVATE hwndTopLevel:00200A16 nHittest:HTVSCROLL uMsg:WM_LBUTTONDOWN
<000306> 00090A5E R WM_MOUSEACTIVATE fuActivate:MA_ACTIVATE
<000307> 00090A5E S WM_SETCURSOR hwnd:00090A5E nHittest:HTVSCROLL wMouseMsg:WM_LBUTTONDOWN
<000308> 00090A5E R WM_SETCURSOR fHaltProcessing:False
<000309> 00090A5E P WM_NCLBUTTONDOWN nHittest:HTVSCROLL xPos:1793 yPos:170
<000310> 00090A5E S WM_SYSCOMMAND uCmdType:SC_HSCROLL xPos:1793 yPos:170
<000311> 00090A5E S WM_VSCROLL nScrollCode:SB_THUMBTRACK nPos:105 hwndScrollBar:(не определено)
<000312> 00090A5E R WM_VSCROLL
<000313> 00090A5E S WM_CAPTURECHANGED hwndNewCapture:00090A5E
<000314> 00090A5E R WM_CAPTURECHANGED
<000315> 00090A5E P WM_MOUSEMOVE fwKeys:MK_LBUTTON xPos:1776 yPos:102
<000316> 00090A5E S WM_VSCROLL nScrollCode:SB_THUMBTRACK nPos:1631 hwndScrollBar:(не определено)
<000317> 00090A5E S WM_STYLECHANGING wStyleType:GWL_EXSTYLE | GWL_STYLE lpss:007FDCF4
<000318> 00090A5E R WM_STYLECHANGING
<000319> 00090A5E S WM_STYLECHANGED wStyleType:GWL_EXSTYLE | GWL_STYLE lpss:007FDCF4
<000320> 00090A5E R WM_STYLECHANGED
<000321> 00090A5E S WM_STYLECHANGING wStyleType:GWL_EXSTYLE | GWL_STYLE lpss:007FDCF4
<000322> 00090A5E R WM_STYLECHANGING
<000323> 00090A5E S WM_STYLECHANGED wStyleType:GWL_EXSTYLE | GWL_STYLE lpss:007FDCF4
<000324> 00090A5E R WM_STYLECHANGED
<000325> 00090A5E S WM_STYLECHANGING wStyleType:GWL_EXSTYLE | GWL_STYLE lpss:007FDCF4
<000326> 00090A5E R WM_STYLECHANGING
<000327> 00090A5E S WM_STYLECHANGED wStyleType:GWL_EXSTYLE | GWL_STYLE lpss:007FDCF4
<000328> 00090A5E R WM_STYLECHANGED
<000329> 00090A5E R WM_VSCROLL
<000330> 00090A5E P WM_LBUTTONUP fwKeys:0000 xPos:1776 yPos:102
<000331> 00090A5E S WM_CAPTURECHANGED hwndNewCapture:00000000
<000332> 00090A5E R WM_CAPTURECHANGED
<000333> 00090A5E S WM_VSCROLL nScrollCode:SB_THUMBPOSITION nPos:1631 hwndScrollBar:(не определено)
<000334> 00090A5E R WM_VSCROLL
<000335> 00090A5E S WM_VSCROLL nScrollCode:SB_ENDSCROLL hwndScrollBar:(не определено)
<000336> 00090A5E R WM_VSCROLL
<000337> 00090A5E R WM_SYSCOMMAND
<000338> 00090A5E S WM_KILLFOCUS hwndGetFocus:(не определено)
<000339> 00090A5E R WM_KILLFOCUS
<000340> 00090A5E S WM_IME_SETCONTEXT fSet:0 iShow:C000000F
<000341> 00090A5E S WM_IME_NOTIFY dwCommand:IMN_CLOSESTATUSWINDOW dwCommand:00000001 dwData:00000000
<000342> 00090A5E R WM_IME_NOTIFY
<000343> 00090A5E R WM_IME_SETCONTEXT
<000344> 00090A5E P WM_MOUSELEAVE
<000345> 00090A5E P WM_PAINT hdc:00000000
<000346> 00090A5E S WM_NCHITTEST xPos:1565 yPos:146
<000347> 00090A5E R WM_NCHITTEST nHittest:HTCLIENT
<000348> 00090A5E S WM_SETCURSOR hwnd:00090A5E nHittest:HTCLIENT wMouseMsg:WM_MOUSEMOVE
<000349> 00090A5E R WM_SETCURSOR fHaltProcessing:False
<000350> 00090A5E P WM_MOUSEMOVE fwKeys:0000 xPos:1557 yPos:3
<000351> 00090A5E S WM_NCHITTEST xPos:1393 yPos:216
<000352> 00090A5E R WM_NCHITTEST nHittest:HTCLIENT
<000353> 00090A5E S WM_SETCURSOR hwnd:00090A5E nHittest:HTCLIENT wMouseMsg:WM_MOUSEMOVE
<000354> 00090A5E R WM_SETCURSOR fHaltProcessing:False
<000355> 00090A5E P WM_MOUSEMOVE fwKeys:0000 xPos:1385 yPos:73
<000356> 00090A5E P WM_PAINT hdc:00000000
<000357> 00090A5E P WM_MOUSELEAVE
<000358> 00090A5E P WM_PAINT hdc:00000000
<000359> 00090A5E S WM_NCHITTEST xPos:1797 yPos:393
<000360> 00090A5E R WM_NCHITTEST nHittest:HTVSCROLL
<000361> 00090A5E S WM_SETCURSOR hwnd:00090A5E nHittest:HTVSCROLL wMouseMsg:WM_MOUSEMOVE
<000362> 00090A5E R WM_SETCURSOR fHaltProcessing:False
<000363> 00090A5E P WM_NCMOUSEMOVE nHittest:HTVSCROLL xPos:1797 yPos:393
<000364> 00090A5E P WM_NCMOUSELEAVE
<000365> 00090A5E S WM_GETTEXT cchTextMax:518 lpszText:007FE3EC
<000366> 00090A5E R WM_GETTEXT cchCopied:0 lpszText:007FE3EC ("$”w±†#ц!")

 
Цитата
null написал:
Он ловит только стандартные.
Если такую простыню кидаете, хотя бы под спойлейр её засунули...  :shock:

Spy++ всё ловит нормально, он либо ловит, либо нет... проверьте, что «Unknown» тип сообщений стоит в настройках. Вот к примеру, перехватил такие сообщения:
Код
<000129> 003C0EF6 P message:0x0118 [Unknown] wParam:0000FFFA lParam:0022B5A4
<000398> 000F035C S message:0x0090 [Unknown] wParam:00000000 lParam:00000000
<000399> 000F035C R message:0x0090 [Unknown] lResult:00000000

Но... это не поможет. Я понаблюдал, при добавлении новых новостей в список, нет никаких сообщений, только WM_PAINT и пр. То-есть, этот самописный контрол работает через прорисовку данных из какой-то внутренней структуры Quik, и никакого отдельного интерфейса к окну MultiList видимо нет, вся логика внутри самого окна. Поэтому, нечего там перехватывать.

Соответственно, пока вижу такой способ. Нужно просто взять размер окна этого MultiList, и затем попиксельно пройтись по нему WM_LBUTTONDOWN прокручивая страницу WM_KEYDOWN(VK_NEXT), одновременно перехватывая обновление окна RichEdit20A. И таким образом, собрать все новости.
 
Цитата
Suntor написал:
Цитата
null   написал:
Он ловит только стандартные.
Если такую простыню кидаете, хотя бы под спойлейр её засунули...  

Spy++ всё ловит нормально, он либо ловит, либо нет... проверьте, что «Unknown» тип сообщений стоит в настройках. Вот к примеру, перехватил такие сообщения:
Код
   <  000129  >  003C0EF6 P  message : 0x0118  [Unknown] wParam:0000FFFA lParam:0022B5A4
 <  000398  >  000F035C S  message : 0x0090  [Unknown] wParam: 00000000  lParam: 00000000 
 <  000399  >  000F035C R  message : 0x0090  [Unknown] lResult: 00000000   

Но... это не поможет. Я понаблюдал, при добавлении новых новостей в список, нет никаких сообщений, только WM_PAINT и пр. То-есть, этот самописный контрол работает через прорисовку данных из какой-то внутренней структуры Quik, и никакого отдельного интерфейса к окну MultiList видимо нет, вся логика внутри самого окна. Поэтому, нечего там перехватывать.

Соответственно, пока вижу такой способ. Нужно просто взять размер окна этого MultiList, и затем попиксельно пройтись по нему WM_LBUTTONDOWN прокручивая страницу WM_KEYDOWN(VK_NEXT), одновременно перехватывая обновление окна RichEdit20A. И таким образом, собрать все новости.
Я видел эти юзер сообщения, они ничего не дают. Размер скрол ареа получить у меня не получилось, а функции получения размера показывают только видимый размер. Так бы легко вычислил размер строки, проскролил, и сэмулировал координаты дабл клика по каждой строке.
Код
const LPRECT rect = new tagRECT();
GetClientRect(hMulti, rect);
const PWINDOWINFO info = new tagWINDOWINFO();
GetWindowInfo(hMulti, info);
 
Цитата
null написал:
Я видел эти юзер сообщения
Ну так значит Spy++ отлично работает, чего на культовую утилиту бочку катить!?...  :evil:

Цитата
null написал:
Размер скрол ареа получить у меня не получилось
GetScrollInfo попробуйте, может выцепит размер?...
 
Цитата
Suntor написал:
Цитата
null   написал:
Я видел эти юзер сообщения
Ну так значит Spy++ отлично работает, чего на культовую утилиту бочку катить!?...  
Цитата
null   написал:
Размер скрол ареа получить у меня не получилось
GetScrollInfo попробуйте, может выцепит размер?...
Как раз его пробовал на MultiView, 0 возвращает.
 
Цитата
null написал:
Цитата
Suntor   написал:
GetScrollInfo попробуйте, может выцепит размер?...
Как раз его пробовал на MultiView, 0 возвращает.
Не поленился, проверил... всё отлично возвращает.

GetScrollInfo для SB_VERT возвращает в SCROLLINFO::nMax вертикальный размер всей клиентской области в пикселах.
GetScrollBarInfo для OBJID_VSCROLL возвращает в SCROLLBARINFO::dxyLineButton высоту ползунка в пикселах, и она для окна MultiList удачно совпадает с высотой строки в пикселах.

Делим одно на другое, и получаем количество строчек в окне новостей. Ну а дальше, уже дело техники...
 
Цитата
GetScrollInfo для SB_VERT возвращает в SCROLLINFO::nMax вертикальный размер всей клиентской области в пикселах.
GetScrollBarInfo для OBJID_VSCROLL возвращает в  SCROLLBARINFO::dxyLineButton высоту ползунка в пикселах, и она для окна  MultiList удачно совпадает с высотой строки в пикселах.
У меня по нулям возвращает...
Код
            const LPSCROLLINFO lpsi = new tagSCROLLINFO();
            GetScrollInfo(hMulti, SB_VERT, lpsi);
            const PSCROLLBARINFO sbi = new tagSCROLLBARINFO();
            GetScrollBarInfo(hMulti, OBJID_VSCROLL, sbi);
 
Цитата
null написал:
У меня по нулям возвращает...
Код
const LPSCROLLINFO lpsi  =  new tagSCROLLINFO();
GetScrollInfo(hMulti, SB_VERT, lpsi);
const PSCROLLBARINFO sbi  =  new tagSCROLLBARINFO();
GetScrollBarInfo(hMulti, OBJID_VSCROLL, sbi);  
Конечно по нулям будет возвращать, размер и маску то не указали...
Код
psi->cbSize = sizeof(SCROLLINFO);
psi->fMask = SIF_ALL;
...
psbi->cbSize = sizeof(SCROLLBARINFO);
 
Цитата
Делим одно на другое, и получаем количество строчек в окне новостей.
Хотелось бы так считать, но Новостей 402, а при делении получаем 337.

 
Цитата
null написал:
Цитата
Делим одно на другое, и получаем количество строчек в окне новостей.
Хотелось бы так считать, но Новостей 402, а при делении получаем 337.
У меня совпало... высота 17 пикселей...

Ну тогда, по-другому можно попробовать. Нужно нажать один раз кнопку полосы прокрутки вниз, чтобы на одну новость прокрутило. И повторно вызвать GetScrollInfo. В SCROLLINFO::nPos тогда уже будет точное значение высоты строки. Вручную попробуйте сначала, на одну новость прокрутить. Запустить тот же код. И посмотреть значение nPos, проверьте расчёт количества nMax/nPos.
 
Цитата
Suntor написал:
Ну тогда, по-другому можно попробовать. Нужно нажать один раз кнопку полосы прокрутки вниз, чтобы на одну новость прокрутило. И повторно вызвать GetScrollInfo. В SCROLLINFO::nPos тогда уже будет точное значение высоты строки. Вручную попробуйте сначала, на одну новость прокрутить. Запустить тот же код. И посмотреть значение nPos, проверьте расчёт количества nMax/nPos.
Даже не так... сам подход неправильный. Будет ошибка округления набегать в любом случае, nPos нужно считать делением всей высоты на количество, а не наоборот.

Короче, нужно из заголовка окна из текста вытаскивать количество. Из nMax вытаскивать высоту клиентской области. Делить второе на первое, и округлять до целого.

То-есть, формула высоты прокрутки строки: h = (int)((double)nMax/(double)n+0.5);
У меня, к примеру, получается: (17930/1083 + 0.5) = (16.56+0.5) = 17
Как раз совпадает с тем, что возвращает в nPos при прокрутке на одну строчку.

Да и вообще, не нужны эти заморочки. Можно проще сделать. Нужно попиксельно пройтись по видимой части клиентской области нажимая мышкой, затем прокрутить страницу PGDOWN, и снова и т.д. до конца. При этом нужно следить за размером nMax, если он изменился в ходе обхода, то прервать процесс и начать заново, так как новая новость пришла. Дальше, держать в памяти количество собранных новостей и nMax, и добавлять уже новые по мере прихода.
 
Нашел способ как найти высоту строки. Но столкнулся с другой проблемой сообщения дабл клика приходят в окно, но новость не обновляется  :sad:
Код
//Вычисляем высоту линии
SetScrollPos(hMulti, SB_VERT, 0, true);
SendMessage(hMulti, WM_VSCROLL, SB_LINEDOWN, 0);
const size_t height = GetScrollPos(hMulti, SB_VERT);

//Вычисляем размер окна
RECT* rect = new RECT();
GetClientRect(hMulti, rect);

// Сбрасываем позицию скрола в 0
SetScrollPos(hMulti, SB_VERT, 0, true); 

// Определяем центр экрана и чуть левее.
const size_t centr = (rect->right - rect->left) / 2 - 100; 

// перебираем все строки до тех пор пока контрольная сумма не равна контрольной сумме предидущей новости == последняя новость
while() {
// Рандом координаты клика по первой строке, проверил все правильно
const size_t x = centr + (rand() % 50);
const size_t y = height + 3 + (rand() % (height - 3));


PostMessage(hMulti, WM_ACTIVATE, WA_ACTIVE, 0);
PostMessage(hMulti, WM_ACTIVATE, WA_CLICKACTIVE, 0);
PostMessage(hMulti, WM_SETFOCUS, 0, 0);
// Двойной клик по новости
SendMessage(hMulti, WM_LBUTTONDBLCLK, MK_LBUTTON, MAKELPARAM(x, y));
Sleep(50);
// Отпускаем левую кнопку мыши
SendMessage(hMulti, WM_LBUTTONUP, 0, MAKELPARAM(x, y));

//Новости нет?

//Скролим на следущую строку
SendMessage(hMulti, WM_VSCROLL, SB_LINEDOWN, 0);
 }
 
Вот сделал более менее рабочий вариант. Но есть глюки, если первая новость помечена не прочитанной, то читает ее только со второго раза. Конец новостей определяет криво, с каждым разом отодвигает ее дальше.
Хотелось бы еще считать кроме текста новости заголовок Новости, время, агенство.

Код
#include "stdafx.h"
#include <Windows.h>
#include <iostream>
#include <commctrl.h>
#include <future>

HWND hNews;

BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam)
{
   hNews = FindWindowEx(hwnd, nullptr, L"InfoNews", nullptr);
   if (hNews != nullptr)
   {
      return FALSE;
   }
   return TRUE;
}

size_t crc32c(const wchar_t* buf, size_t len)
{
   size_t crc = ~0U;

   if (len == 0) return crc;

#if defined(__x86_64__) || defined(_M_X64)
   while (len >= 8)
   {
      crc = _mm_crc32_u64(crc, *reinterpret_cast<const std::uint64_t*>(buf));
      len -= 8;
      buf += 8;
   }
#endif

   while (len >= 4)
   {
      crc = _mm_crc32_u32(crc, *reinterpret_cast<const std::uint32_t*>(buf));
      len -= 4;
      buf += 4;
   }

   while (len >= 2)
   {
      crc = _mm_crc32_u16(crc, *reinterpret_cast<const std::uint16_t*>(buf));
      len -= 2;
      buf += 2;
   }
   while (len >= 1)
   {
      crc = _mm_crc32_u8(crc, *reinterpret_cast<const std::uint8_t*>(buf));
      len -= 1;
      buf += 1;
   }

   return crc;
}

int main()
{
   setlocale(LC_ALL, "Russian");
   const HWND hWnd = FindWindow(L"InfoClass", nullptr);

   if (hWnd != nullptr)
   {
      const HWND hMdi = FindWindowEx(hWnd, nullptr, L"MDIClient", nullptr);

      if (hMdi != nullptr)
      {
         EnumChildWindows(hMdi, EnumChildProc, 0);
         if (hNews != nullptr)
         {
            const HWND hMulti = FindWindowEx(hNews, nullptr, L"MultiList", nullptr);
            const HWND hRich = FindWindowEx(hNews, nullptr, L"RichEdit20A", nullptr);

            if (hRich != nullptr && hMulti != nullptr)
            {
               SCROLLINFO* si = new SCROLLINFO();
               si->cbSize = sizeof(SCROLLINFO);
               si->fMask = SIF_ALL;
               GetScrollInfo(hMulti, SB_VERT, si);

               size_t current_pos = GetScrollPos(hMulti, SB_VERT);

               SendMessage(hMulti, WM_VSCROLL, SB_TOP, 0);
               SendMessage(hMulti, WM_VSCROLL, SB_LINEDOWN, 0);

               const size_t height = GetScrollPos(hMulti, SB_VERT);

               const size_t tlen = SendMessage(hNews, WM_GETTEXTLENGTH, NULL, NULL);
               wchar_t* title = new wchar_t[tlen + 1];
               SendMessage(hNews, WM_GETTEXT, tlen + 1, LPARAM(title));

               RECT* rect = new RECT();
               GetClientRect(hMulti, rect);

         
               size_t last_CRC = 0;
               size_t last_LEN = 0;

               size_t current_CRC = 1;
               size_t current_LEN = 1;

               const size_t centr = (rect->right - rect->left) / 2 - 100;
               size_t count = 0;
               
               SendMessage(hMulti, WM_VSCROLL, SB_TOP, 0);
               srand(time(nullptr));
               while (last_CRC != current_CRC || last_LEN != current_LEN)
               {
                  last_CRC = current_CRC;
                  last_LEN = current_LEN;
                  const size_t x = centr + rand() % 50;
                  const size_t y = height + 3 + rand() % (height - 3);
                  const LPARAM pos = MAKELPARAM(x, y);
                  PostMessage(hMulti, WM_ACTIVATE, WA_CLICKACTIVE, 0);
                  // Перемещаем курсор
                  SendMessage(hMulti, WM_MOUSEMOVE, 0, pos);
                  // Дабл клик по новости
                  SendMessage(hMulti, WM_LBUTTONDBLCLK, MK_LBUTTON,pos);
                  // Отпускаем левую кнопку мыши
                  SendMessage(hMulti, WM_LBUTTONUP, 0, pos);

                  // Клик по новости
                  SendMessage(hMulti, WM_LBUTTONDOWN, MK_LBUTTON, pos);
                  // Отпускаем левую кнопку мыши
                  SendMessage(hMulti, WM_LBUTTONUP, 0, pos);

                  //Sleep(10);
                  PostMessage(hMulti, WM_ACTIVATE, WA_INACTIVE, 0);
                  current_LEN = SendMessage(hRich, WM_GETTEXTLENGTH, NULL, NULL);
                  wchar_t* buff = new wchar_t[current_LEN + 1];
                  SendMessage(hRich, WM_GETTEXT, current_LEN + 1, LPARAM(buff));
                  current_CRC = crc32c(buff, current_LEN);

                  // Next line;
                  SendMessage(hMulti, WM_VSCROLL, SB_LINEDOWN, 0);
                  Sleep(50);
                  count++;
                  //std::wcout << count << std::endl << buff << std::endl << std::endl << std::endl << std::endl;
               }

               std::cout << count << std::endl;
            }
         }
      }
   }

   std::cout << "done" << std::endl;

}


 
Цитата
null написал:
Нашел способ как найти высоту строки. Но столкнулся с другой проблемой сообщения дабл клика приходят в окно, но новость не обновляется  
Код
  //Вычисляем высоту линии
SetScrollPos(hMulti, SB_VERT,  0 ,  true );
SendMessage(hMulti, WM_VSCROLL, SB_LINEDOWN,  0 );
const size_t height  =  GetScrollPos(hMulti, SB_VERT);  
Собственно, я об этом и написал перед этим... прокрутить на одну строчку вниз, и посмотреть nPos в GetScrollInfo, ну или как вы получаете тоже значение через GetScrollPos.

Цитата
null написал:
Вот сделал более менее рабочий вариант.
Мягко говоря... совсем «код новичка» так сказать. Ну по порядку:

Цитата
null написал:
Код
BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam)
{
   hNews  =  FindWindowEx(hwnd, nullptr, L"InfoNews", nullptr);
    if  (hNews  !  =  nullptr)  
Зачем?... в эту ф-цию обратного вызова и так идут все хендлы детей и их детей и т.д.... не нужно в ней ещё поддетей детей проверять... здесь нужно взять имя класса через GetClassName и сравнить его с "InfoNews".

Цитата
null написал:
Код
      const HWND hMdi  =  FindWindowEx(hWnd, nullptr, L"MDIClient", nullptr);

       if  (hMdi  !  =  nullptr)
      {
Зачем?... Не нужно MDIClient получать, можно сразу для InfoNews вызывать EnumChildWindows.

Цитата
null написал:
Код
               const size_t centr  =  (rect -  > right  -  rect -  > left) /  2   -   100 ;
               
                  const size_t x  =  centr  +  rand() %  50 ;
                  const size_t y  =  height  +   3   +  rand() % (height  -   3 );
                  const LPARAM pos  =  MAKELPARAM(x, y);  
Что за адские вычисления?... через rand() с остатком? это вообще зачем?

Цитата
null написал:
Код
                  PostMessage(hMulti, WM_ACTIVATE, WA_CLICKACTIVE,  0 );
                  // Перемещаем курсор
                  SendMessage(hMulti, WM_MOUSEMOVE,  0 , pos);
                  // Дабл клик по новости
                  SendMessage(hMulti, WM_LBUTTONDBLCLK, MK_LBUTTON,pos);
                  // Отпускаем левую кнопку мыши
                  SendMessage(hMulti, WM_LBUTTONUP,  0 , pos);

                  // Клик по новости
                  SendMessage(hMulti, WM_LBUTTONDOWN, MK_LBUTTON, pos);
                  // Отпускаем левую кнопку мыши
                  SendMessage(hMulti, WM_LBUTTONUP,  0 , pos);

                  //Sleep( 10 );
                  PostMessage(hMulti, WM_ACTIVATE, WA_INACTIVE,  0 );
                  current_LEN  =  SendMessage(hRich, WM_GETTEXTLENGTH, NULL, NULL);
                  wchar_t *  buff  =  new wchar_t[current_LEN  +   1 ];
                  SendMessage(hRich, WM_GETTEXT, current_LEN  +   1 , LPARAM(buff));
                  current_CRC  =  crc32c(buff, current_LEN);

                  // Next line;
                  SendMessage(hMulti, WM_VSCROLL, SB_LINEDOWN,  0 );  
Вот честно не нравится мне это... совсем... Мне кажется это нужно по-другому вообще сделать. Нужно сначала SetFocus() на MultiList сделать, а потом вообще клавиатурой пройтись по всему списку нажимая кнопки VK_DOWN и VK_RETURN. Так с ходу не могу сказать, нужно экспериментировать... но мне кажется, что это лучше, чем вычисление координат и  тыкание мышкой...

Цитата
null написал:
Код
               SCROLLINFO *  si  =  new SCROLLINFO();

               wchar_t *  title  =  new wchar_t[tlen  +   1 ];

               RECT *  rect  =  new RECT();

                  wchar_t *  buff  =  new wchar_t[current_LEN  +   1 ];  
Ну и наконец — самое главное — «гвоздь „программы”» в прямом и переносном смысле: где delete???
Вы везде ставите new, в том числе и в цикл его засунули, но при этом не делаете delete. У вас в программе сплошные утечки памяти идут.
Да и не нужны new для тех же структур WinAPI, зачем?... все эти структуры локально на стеке выделить и проинициализировать:
Код
SCROLLINFO si = {sizeof(SCROLLINFO)};
si.fMask = SIF_ALL;
if (!GetScrollInfo(hMulti, SB_VERT, &si)) /*ошибка*/;
...
RECT rect;
if (!GetClientRect(hMulti, &rect)) /*ошибка*/; 
и вызовы самих ф-ций на ошибки тоже нужно проверять... ну и т.д.
 
Цитата

Зачем?... в эту ф-цию обратного вызова и так идут все хендлы детей и их детей и т.д.... не нужно в ней ещё поддетей детей проверять... здесь нужно взять имя класса через GetClassName и сравнить его с "InfoNews".

Вот честно не нравится мне это... совсем... Мне кажется это нужно по-другому вообще сделать. Нужно сначала SetFocus() на MultiList сделать, а потом вообще клавиатурой пройтись по всему списку нажимая кнопки VK_DOWN и VK_RETURN.Ну и наконец — самое главное — «гвоздь „программы”» в прямом и переносном смысле: где delete???
Вы везде ставите new, в том числе и в цикл его засунули, но при этом не делаете delete. У вас в программе сплошные утечки памяти идут.
Да и не нужны new для тех же структур WinAPI, зачем?... все эти структуры локально на стеке выделить и проинициализировать:
Код
  SCROLLINFO si  =  {sizeof(SCROLLINFO)};
si.fMask  =  SIF_ALL;
 if  ( ! GetScrollInfo(hMulti, SB_VERT,  & si)) / * ошибка * /;
 .. .
RECT rect;
 if  ( ! GetClientRect(hMulti,  & rect)) / * ошибка * /; 
  
и вызовы самих ф-ций на ошибки тоже нужно проверять... ну и т.д.

Зачем? был какой-то глюк со свернутым окном, просто не находил InfoNews. Это еще не программа, это лишь прототип в консоли для проверки, всегда освобождаю. Насчет  VK_DOWN и VK_RETURN попробую.
 
Цитата
null написал:
был какой-то глюк со свернутым окном, просто не находил InfoNews
свёрнутось окна не должна влиять, глюк был в чём-то другом... берите самое верхнее окно и от него делайте перебор детей... всё должно работать
 
Я не знаю, можно ли через LUA разбирать текстовые файлы. Лет 5 назад надо было парсить появление новостей в квике. В директории квика есть файл с новостями. Я вызывал системный класс, ловящий изменение файла в системе. Получив событие просто текстово парсил файл. Какой именно сейчас не вспомню, он увесистый, если в настройках выставить хранить новости несколько дней то ббудет несколько мегабайт. Я не разбирался как там раскодировать дату сообщений, но заголовок и текст довольно легко достаются. Помоему это куда проще чем то что вы описываете выше.
 
Покопался в архивах, раньше файл назывался news.log, возможно название изменилось. Файл начинается с INFONEWS, строки оканчиваются нулём.
Вот немного полезной инфы про отслеживания за изменениями файлов в директории https://habr.com/post/164775/
 
Цитата
Юрий написал:
Я не знаю, можно ли через LUA разбирать текстовые файлы. Лет 5 назад надо было парсить появление новостей в квике. В директории квика есть файл с новостями. Я вызывал системный класс, ловящий изменение файла в системе. Получив событие просто текстово парсил файл. Какой именно сейчас не вспомню, он увесистый, если в настройках выставить хранить новости несколько дней то ббудет несколько мегабайт. Я не разбирался как там раскодировать дату сообщений, но заголовок и текст довольно легко достаются. Помоему это куда проще чем то что вы описываете выше.
Тоже думал над этим, спасибо. Бегло прошелся хекс редактором, показалось там не полный текст новости. Попробую на досуге еще раз поковырять файл. Дата вероятно там упаковывается в DWORD.
 
Цитата
Юрий написал:
Покопался в архивах, раньше файл назывался news.log, возможно название изменилось. Файл начинается с INFONEWS, строки оканчиваются нулём.
Идея хорошая... смущает только одна вещь. Посмотрел у себя этот файл, и такое впечатление, что там только заголовки новостей и те новости, которые читались. То-есть, если в окне новостей щёлкнуть на новость и её текст появится в
RichEdit20A, то он сохраняется в news.log. А если новость не читали, то её нет в news.log.
 
Вот самый стабильный вариант. Осталось решить одну проблему - первые пару новых не прочитанных новостей читаются пустым, при повторном запуске читаются нормально. Хотя не особо проблема.
Принцип работы с заголовка парсится количество новостей(в окне). Дальше перебираем каждую строку до количества новостей. Осталось спарсить дату, агенство, заголовок. Есть идеи?

Код
#include "stdafx.h"
#include <Windows.h>
#include <iostream>
#include <string>
#include <immintrin.h>
#include <fstream>
#include <ctime>
#include <regex>

HWND hNews = nullptr;

BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam)
{
   wchar_t *cname = new wchar_t[128];
   if(GetClassName(hwnd, cname, 128) && !wcscmp(cname, L"InfoNews"))
   {
         hNews = hwnd;
         delete[] cname;
         return false;      
   }

   delete[] cname;
   return true;
}

std::uint32_t crc32c(const wchar_t* buf, size_t len)
{
   std::uint32_t crc = ~0U;

   if (len == 0) return crc;

#if defined(__x86_64__) || defined(_M_X64)
   while (len >= 8)
   {
      crc = _mm_crc32_u64(crc, *reinterpret_cast<const std::uint64_t*>(buf)) & 0xffffffff;
      len -= 8;
      buf += 8;
   }
#endif

   while (len >= 4)
   {
      crc = _mm_crc32_u32(crc, *reinterpret_cast<const std::uint32_t*>(buf));
      len -= 4;
      buf += 4;
   }

   while (len >= 2)
   {
      crc = _mm_crc32_u16(crc, *reinterpret_cast<const std::uint16_t*>(buf));
      len -= 2;
      buf += 2;
   }
   while (len >= 1)
   {
      crc = _mm_crc32_u8(crc, *reinterpret_cast<const std::uint8_t*>(buf));
      len -= 1;
      buf += 1;
   }

   return crc;
}

int main()
{
   const std::locale locale("Russian_Russia");
   std::locale::global(locale);

   std::wofstream LogFile("C:\\tools\\news.txt", std::ios::out);
   if (!LogFile.good())
   {
      return 1;
   }
   const HWND hWnd = FindWindow(L"InfoClass", nullptr);


   EnumChildWindows(hWnd, EnumChildProc, 0);
   if (hNews != nullptr)
   {
      const HWND hMulti = FindWindowEx(hNews, nullptr, L"MultiList", nullptr);
      const HWND hRich = FindWindowEx(hNews, nullptr, L"RichEdit20A", nullptr);

      if (hRich != nullptr && hMulti != nullptr)
      {
         SendMessage(hMulti, WM_VSCROLL, SB_TOP, 0);
         SendMessage(hMulti, WM_VSCROLL, SB_LINEDOWN, 0);

         const size_t height = GetScrollPos(hMulti, SB_VERT);

         if (height < 1)
         {
            std::cout << "Ошибка получения высоты линии!" << std::endl;
            return 1;
         }

         RECT* rect = new RECT();
         if (!GetClientRect(hMulti, rect))
         {
            std::cout << "Ошибка получения GetClientRect!" << std::endl;
            return 1;
         }


         const size_t centr = (rect->right - rect->left - 200) / 2;
         size_t count = 0;

         delete rect;

         SendMessage(hMulti, WM_VSCROLL, SB_TOP, 0);
         srand(time(nullptr) & 0xffffffff);

         PostMessage(hMulti, WM_ACTIVATE, WA_ACTIVE, 0);
         SendMessage(hMulti, WM_SETFOCUS, 0, 0);

         const size_t tlen = SendMessage(hNews, WM_GETTEXTLENGTH, NULL, NULL);
         wchar_t* title = new wchar_t[tlen + 1];
         SendMessage(hNews, WM_GETTEXT, tlen + 1, LPARAM(title));

         const std::regex re("(\\d+).*?(\\d+)\\;");

         std::wstring ws(title);
         const std::string line(ws.begin(), ws.end());

         std::smatch match;

         if (std::regex_search(line, match, re))
         {
            const std::string num = match[2];
            std::cout << "Количество Новостей: ";
            std::cout << num << std::endl;
            count = std::stoi(num);
         }

         delete[] title;

         // Перемещаем курсор на строку первой новости.
         const size_t x = centr + rand() % 50;
         const size_t y = height + 3 + rand() % (height - 3);
         const LPARAM pos = MAKELPARAM(x, y);

         SendMessage(hMulti, WM_MOUSEMOVE, 0, pos);
         // Клик по первой новости
         SendMessage(hMulti, WM_LBUTTONDOWN, MK_LBUTTON, pos);
         // Отпускаем левую кнопку мыши
         SendMessage(hMulti, WM_LBUTTONUP, 0, pos);

         // Жмем return
         SendMessage(hMulti, WM_KEYDOWN, VK_RETURN, 0x001C0001);
         SendMessage(hMulti, WM_KEYUP, VK_RETURN, 0x001C0001);

         size_t current_LEN = SendMessage(hRich, WM_GETTEXTLENGTH, NULL, NULL);
         wchar_t* buff = new wchar_t[current_LEN + 1];
         SendMessage(hRich, WM_GETTEXT, current_LEN + 1, LPARAM(buff));
         size_t current_CRC = crc32c(buff, current_LEN);
         LogFile << L"\r\nНомер: 1 Длина: " + std::to_wstring(current_LEN) + L" CRC: " + std::to_wstring(current_CRC)
            + L"\r\n" << std::endl;
         LogFile << buff << std::endl;
         delete[] buff;

         for (size_t i = 2; i <= count; i++)
         {
            SendMessage(hMulti, WM_KEYDOWN, VK_DOWN, 0x01500001);
            // Жмем стрелочку вниз
            SendMessage(hMulti, WM_KEYUP, VK_DOWN, 0xC1500001);

            // Жмем return
            SendMessage(hMulti, WM_KEYDOWN, VK_RETURN, 0x001C0001);
            SendMessage(hMulti, WM_KEYUP, VK_RETURN, 0x001C0001);

            current_LEN = SendMessage(hRich, WM_GETTEXTLENGTH, NULL, NULL);
            wchar_t* nbuff = new wchar_t[current_LEN + 1];
            SendMessage(hRich, WM_GETTEXT, current_LEN + 1, LPARAM(nbuff));
            current_CRC = crc32c(nbuff, current_LEN);
            LogFile << L"\r\nНомер: " + std::to_wstring(i) + L" Длина: " + std::to_wstring(current_LEN) + L" CRC: "
               + std::to_wstring(current_CRC) + L"\r\n" << std::endl;
            LogFile << nbuff << std::endl;
            delete[] nbuff;
            Sleep(1);
         }


         SendMessage(hMulti, WM_KILLFOCUS, 0, 0);
         PostMessage(hMulti, WM_ACTIVATE, WA_INACTIVE, 0);

         std::cout << count << std::endl;
      }
   }
   LogFile.close();
   std::cout << "done" << std::endl;
   return 0;
}


 
Цитата
Suntor написал:
Цитата
Юрий   написал:
Покопался в архивах, раньше файл назывался news.log, возможно название изменилось. Файл начинается с INFONEWS, строки оканчиваются нулём.
Идея хорошая... смущает только одна вещь. Посмотрел у себя этот файл, и такое впечатление, что там только заголовки новостей и те новости, которые читались. То-есть, если в окне новостей щёлкнуть на новость и её текст появится в
RichEdit20A, то он сохраняется в news.log. А если новость не читали, то её нет в news.loЯ
Я точно не помню, посмотрите в настройках квика, нет ли там опции читать все новости с сервера и сохранять. Я тело новости не парсил, мне нужны были только заголовки.
 
Цитата
null написал:
Вот самый стабильный вариант.
1. Не злоупотребляйте new/delete операциями. Это очень тяжёлые ресурсоёмкие операции, которые приводят к вызову системных ф-ций выделения памяти из кучи и пр. При этом исполняется код объёмом под 150 КБ... поэтому, всегда нужно стараться использовать обычные переменные на стеке, память под которые выделяется всего одной инструкцией процессора записи в регистр указателя стека... Я уже выше писал об этом про структуры. Но тоже самое касается и массивов с константным размером. Например ваш код:
Код
wchar_t *cname = new wchar_t[128];
if(GetClassName(hwnd, cname, 128) && !wcscmp(cname, L"InfoNews"))
...
delete[] cname;
можно ускорить в сотни раз:
Код
wchar_t cname[256];
if(GetClassName(hwnd, cname, _countof(cname)) && !wcscmp(cname, L"InfoNews"))

2. Максимальный размер имени класса окна в WNDCLASSEX равен 256, а не 128.

3. Ещё раз посмотрел весь код, и та же мысль... ну не так. Вообще не нужно количество новостей из заголовка вытаскивать. И мышка не нужна. И координаты не нужны. Нужно:
• нажать Ctrl+End (окно прокрутится вниз, и выделится самая последняя новость), а затем Enter (новость появится в RichEdit20A);
• далее в цикле идти вверх, нажимать UpArrow+Enter, читая новости и считая их количество и следя за сдвигом ползунка;
• в самом верху, как только позиция ползунка обнулилась, выходим из цикла;
В итоге, все новости прочитаны и их количество подсчитано. Да ещё в придачу, если в момент нашего цикла пришла новая новость, то ничего страшного, к моменту прихода нашего цикла вверх, она также обработается и подсчитается.

4. Про разбор даты, агентства и заголовка. Посмотрел формат там у всех агентств разный. Поэтому, если и делать разбор, то нужно сначала пробежать по новости, и поискать там ключевые слова: «ПРАЙМ», «Interfax» и пр.. То-есть, определить новостное агентство. И уже затем, для каждого из них, разбирать отдельно. У Интерфакса, за вычетом пустых строк, идёт в первой строчке дата, во второй ключ. слова, в следующей заголовок, и далее тело. Для ПРАЙМ всё слитно, вначале дата, и далее сразу тело новости без заголовка. Ну и т.д. Тут конечно можно поизвращаться, но что-то красивое и универсальное не сделать, скорее всего...
 
Цитата
Юрий написал:
Я точно не помню, посмотрите в настройках квика, нет ли там опции читать все новости с сервера и сохранять. Я тело новости не парсил, мне нужны были только заголовки.
Есть флажок «Запрашивать тело новости вместе с заголовком». Но надо проверять, то или не то. Может и запрашивает, но в файл news.log не будет сохранять.
 
а что-то изменилось за годы? появилось какое то простое api для работы с новостями?
или это очень трудно реализуемо ...
 
Александр, добрый день!

На текущий момент подобного API нет.
Можем зарегистрировать пожелание на доработку. Для этого просим подробнее описать желаемый функционал.
 
Добрый день!

Roman Azarov, Идея то хорошая.

Вот пожелание на доработку:
-надо иметь возможность задать идентификатор для конкретной таблицы новостей (как для графиков), так как таблиц с новостями можно открыть много и на каждую из них повесить свой фильтр и свой идентификатор.
-нужна возможность программно обратиться к таблице по идентификатору, перебрать строки-новости в составе полей (Дата, Время, Агентство, Заголовок, Новость) и в переменную засунуть нужную мне новость.

А все остальное можно получить оттуда строковыми функциями и проанализировать.

Думаю, это для вас абсолютно не сложно, тем более такой функционал есть для всех остальных основных таблиц - ничего не надо придумывать. Только идентификатор таблицы добаить.  

Зачем нужна возня с какими-то внешними компонентами, если это можно будет спокойно реализовать на QLUA ?!
 
Не должно быть никакой привязки к визуальной таблице
Должен быть чисто программный интерфейс на манер CreateDataSouce c последующим вызовом call-back функции на каждую новость.
И API перебора всех уже имеющихся новостей.
 
Цитата
swerg написал:
Не должно быть никакой привязки к визуальной таблице
Не нравятся мне безапелляционные сообщения подобного рода. Если Вы так пишите - аргументируйте.

Я исхожу из того, что решение должно быть быстро реализуемым и удобным для большого количества пользователей QUIK, использующих QLUA в своих целях, а не для узкого круга супер-пупер программеров, пишущих на заказ... С таким подходом, который Вы озвучили, вообще не надо никакого интерфейса - достаточно получать котировки.

...Хотя, если разработчик сочтет Ваш вариант более подходящим, то не имею ничего против, главное, чтобы это не затянулось по времени и работало.
 
Цитата
Олег написал:
Цитата
swerg написал:
Не должно быть никакой привязки к визуальной таблице
Не нравятся мне безапелляционные сообщения подобного рода. Если Вы так пишите - аргументируйте.

Каковы ваши цели?
И где аргументация с вашей стороны?
Есть ваше мнение общие рассуждения по поводу "решение должно быть быстро реализуемым", "удобным для большого количества пользователей QUIK". На речи депутатов похоже, общие слова "за мир во всем мире".

Что вам нужно аргументировать? то, что в скрипте должен быть контролируемый полностью доступ к данным? Считаю, что это очевидно.
Или быть может вас устраивает ситуация, когда сейчас чтобы получить свечей приходилось бы открывать графики, задавать на них какие-то "идентификаторы", лазить по меню и что-то нам настраивать чтобы в скрипте в итоге поехал поток данных? это удобно??
Очевидно же что нет.
Так что требуется аргументировать?

И, главное, с чего вы считаете, что я для вас что-то должен аргументировать?
 
swerg, Вообще-то, любое высказывание следует аргументировать - даже самые очевидные вещи. Ибо то, что очевидно для Вас, может быть совершенно не очевидно для собеседника. Тем более, что это не личка, а форум. Для меня вот совершенно очевидно, что тип integer обязан быть в языке - это первый язык, который я встретил за долгие годы программирования, в котором его нет! И что? Его нет и не будет - как ни аргументируй.

Для меня вот Ваше высказывание "не должно быть никакой привязки к визуальной таблице" не только не очевидно, но я вообще считаю его бредом сивой кобылы. Равно как и "должен быть чисто программный интерфейс на манер CreateDataSouce c последующим вызовом call-back функции на каждую новость". Худшего интерфейса, чем CreateDataSouce ещё поискать! Тем более, что все "свечные" утилиты лежат в разделе "функции для работы с графиками". ПРИ ЧЁМ ТУТ ВАЩЕ ГРАФИКИ?!

Что такое "визуальная таблица", я не знаю, и знать не хочу. Не бывает в природе никаких "визуальных таблиц"! Вот, скажем, ТТТ - основная таблица, с которой работает мой скрипт - она какая, визуальная? Да, чего-то там мельтешит в отдельной вкладке, но я туда и не заглядываю никогда - она мне нужна только для заказа данных по интересующему меня набору тикеров. А вот скрипт мой постоянно там ковыряется, ибо "привязан к визуальной таблице". :smile:

Предложение Олега разумно: должен быть удобный и унифицированный доступ к любым данным любых таблиц (исключая какие-нибудь секретные и служебные поля), и таблица новостей НИЧЕМ в этом плане не отличается от любой другой таблицы: те же строки, только вид сбоку.
 
Цитата
Владимир написал:

Для меня вот совершенно очевидно, что тип integer обязан быть в языке - это первый язык, который я встретил за долгие годы программирования, в котором его нет! И что? Его нет и не будет - как ни аргументируй.

про ассемблер слышал разработчик операционных систем? А про Forth?  Неужели про Бейсик тоже не в курсах? И про все остальные скриптовые языки со слабой типизацией тоже нет? Никогда не использовали sql ?

языков , которых по вашему мнению не существует, абсолютное  большинство.


какие интересные операционные системы...
www.bot4sale.ru

Пасхалочка для Алексея Иванникова: https://forum.quik.ru/messages/forum10/message63088/topic7052/#message63088
 
Пример: База данных. в ней много таблиц. Пока не откроешь таблицу, т.е. визуализируешь данные, прочитать из таблицы ничего нельзя.
Очевидно, что так это не работает.

ТТТ - это визуализация данных в терминале. Но ее можно и не открывать, т.к. key-value, связанный с этой "таблицей", находится в памяти и доступен для чтения через публичные методы. Поэтому есть необходимость реализации методов для всех, так называемых "таблиц" Квика.

Привязка же к графикам - это просто один из методов, считывания информации с этого графика, со всеми вытекающими проблемами. И зачастую, используется не для получения данных баров (свечек).
 
s_mike@rambler.ru,  Лапуль, про ассемблер я не только слышал, но и писал аж на ТРЁХ ассемблерах (БЭСМ, PDP и Intel). И на Васике тоже доводилось писать. Для справки: тип integer в любом ассемблере был, есть и будет ВСЕГДА! Это как раз наоборот, типа float нам когда-то не было - он появился позже, [тогда ещё] отдельным сопроцессором и со своей системой команд. Вот sql действительно не использовал никогда - я чуть не всю свою сознательную жизнь занимался сложными базами данных, и моя давняя фраза на эту тему звучит так: "Базы данных могут быть либо сложными либо реляционными, но не тем и другим одновременно". И тыщу раз говорил, что за "слабую типитзацию" руки-ноги бы повыдёргивал тем умникам, которые выродили эту бредятину.

Nikolay, ЧАВО?! Во-первых, В МОИХ базах данных, как правило, ОДНА таблица (неоднородных кортежей).  :smile: Во-вторых, какое отношение имеет открытие таблицы к визуализации? ТТТ - это ХРАНЕНИЕ данных в терминале, а никакая не "визуализация". И доступ к ней как раз "ракообразный", через getParamEx, а не getItem, скажем. Разумного объяснения сему факту лично я найти не могу. Привязка же доступа к графикам - это КРЕТИНИЗМ! АДНАЗНАЧНА!
 
Цитата
Владимир написал:
   s_mike@rambler.ru,  Лапуль, про ассемблер я не только слышал, но и писал аж на ТРЁХ ассемблерах (БЭСМ, PDP и Intel). И на Васике тоже доводилось писать. Для справки: тип integer в любом ассемблере был, есть и будет ВСЕГДА! Это как раз наоборот, типа float нам когда-то не было - он появился позже, [тогда ещё] отдельным сопроцессором и со своей системой команд. Вот sql действительно не использовал никогда - я чуть не всю свою сознательную жизнь занимался сложными базами данных, и моя давняя фраза на эту тему звучит так: "Базы данных могут быть либо сложными либо реляционными, но не тем и другим одновременно". И тыщу раз говорил, что за "слабую типитзацию" руки-ноги бы повыдёргивал тем умникам, которые выродили эту бредятину.

Nikolay, ЧАВО?! Во-первых, В МОИХ базах данных, как правило, ОДНА таблица (неоднородных кортежей).  :: Во-вторых, какое отношение имеет открытие таблицы к визуализации? ТТТ - это ХРАНЕНИЕ данных в терминале, а никакая не "визуализация". И доступ к ней как раз "ракообразный", через getParamEx, а не getItem, скажем. Разумного объяснения сему факту лично я найти не могу. Привязка же доступа к графикам - это КРЕТИНИЗМ! АДНАЗНАЧНА!
добавлю свою ложку...
тип float в ассемблере существует всегда и он не зависит от наличия сопроцессора.
Типы вводятся в язык по причине необходимости работать с ними.
float - это способ хранить числа в большем диапазоне значений
с экономией памяти, но с допустимой погрешностью.
альтернативой был двоично-десятичный тип  - позволявший точно хранить финансовые данные.
---------------
Но в языках нет понятия "бредятина"
----------------------------------------------------
Если что-то не понятно, то зеркало не виновато.
 
nikolz, Что, сегодня в Кащенко день открытых дверей? :smile:

Лапуль, ЛЮБОЙ тип данных (в т.ч. и тип float) существует тогда и ТОЛЬКО тогда, если к нему имеются а) общие правила целостности, ограничивающие набор экземпляров этого типа и б) коллекции операций, применимых к таким экземплярам. Не соблаговолите ли привести эти данные для типа float, который "в ассемблере существует всегда и не зависит от наличия сопроцессора"? :wink:

И кто Вам сказал, что "float - это способ хранить числа в большем диапазоне значений с экономией памяти, но с допустимой погрешностью"? Да только я только на этом форуме несколько раз тыкал носом таких умников, показывая, что UI64 позволяет хранить все 19-значные числа и даже часть 20-значных, и что на это Ваш сраный float в принципе не способен. А эта грёбаная "динамическая типизация" есть именно БРЕДЯТИНА! Говно, способное испохабить любой язык.
 
Цитата
Владимир написал:
   Nikolay, ЧАВО?! Во-первых, В МОИХ базах данных, как правило, ОДНА таблица (неоднородных кортежей).  :: Во-вторых, какое отношение имеет открытие таблицы к визуализации? ТТТ - это ХРАНЕНИЕ данных в терминале, а никакая не "визуализация". И доступ к ней как раз "ракообразный", через getParamEx, а не getItem, скажем. Разумного объяснения сему факту лично я найти не могу. Привязка же доступа к графикам - это КРЕТИНИЗМ! АДНАЗНАЧНА!

... ТТТ - это ХРАНЕНИЕ данных в терминале ... оставлю без комментариев

"Во-вторых, какое отношение имеет открытие таблицы к визуализации?"
Вы таблицу зачем открываете? Смотреть глазами? Не надо смотреть, то зачем открывать. А если смотреть, то какие претензии к термину "визуализация".

Доступ к данным параметров корректный. Обычный запрос на получение данных key-value по ключу параметра.
 
Nikolay,
Цитата
Вы таблицу зачем открываете? Смотреть глазами?
ЩАЗ! А файл я зачем открываю? Чтобы получить его идентификатор (handle) и в дальнейшем работать с ним по этому идентификатору. А глазами-то мне зачем на неё смотреть? Что я там увижу? Это в таблице моего скрипта, в миллион раз более наглядной, можно что-то увидеть - вот она именно ДЛЯ ВИЗУАЛИЗАЦИИ, для юзера - скрипту она нафиг не нужна. Да и мне она уже не нужна - только захочешь что-нибудь купить или продать, потянешься за мышкой - БАБАХ! А она уже всё сделала. :smile:

Какой ещё "доступ к данным параметров корректный"? Вот я буквально вчера писал в другой ветке:

1. Мне хотелось бы получать с сервера свечи (от 15-минутных и выше), при этом меня интересуют только последние две свечи по каждому таймфрейму, можно даже без коллбеков - только доступ к этим данным.

2. Я не умею программно прочесть состояние своего портфеля (та табличка, которая зелёненьким цвет текста выводит). Портфель я, ессно, веду у себя, но время от времени случаются сбои и рассогласование содержимого портфеля с точки зрения брокера и самого скрипта. Примерно раз в неделю я это дело проверяю (вручную) и убираю нестыковки. А хотелось бы делать это программно, примерно раз в полчаса. Никто не знает, как это сделать?
 
РебятЫ, давайте жить дружно!

У каждого свой уровень программирования, у каждого свой уровень понимания вопроса, у каждого свои любимые инструменты и приемчики и у каждого свои потребности. У каждого свои скрипты и, что самое главное, ОНИ РАБОТАЮТ. Но все мы работаем в QUIK и это ДАННОСТЬ. И нет смысла ломать палки - есть ли Float в ассемблере или нет его. Я пользуюсь тем функционалом, который мне дают и он пока меня устраивает. Я не выгружаю данные куда-то наружу, чтобы анализировать их в C++, я не пишу коннекты и внешние компоненты, меня устраивает QLUA - все, что мне надо - все работает и в этой среде. Да, я считываю значения свечек и индикаторов по идентификатору и не вижу в этом ничего ужасного, все так же хорошо работает и на таймфрейме и 3, и 5, и 6, и 10 - благодаря этому я могу оперативно сверить результаты работы своего скрипта с результатами в таблицах и на графиках и у меня нет никаких расхождений.

Теперь по вопросу ветки: мне надо всего-навсего прочитать очередную новость, найти нужные там вхождения и сделать в зависимости от этого определенные вычисления - И ВСЕ! Поэтому я и имел ввиду использование уже имеющегося механизма обращения к объекту через идентификатор, чтобы ускорило процесс разработки. Это мой взгляд на вещи. В этом механизме мне все понятно - что и куда...  Зачем усложнять?

И конечно, хотелось бы услышать мнение разработчика QUIK, а не перебранку на пустом месте адептов разных программистских течений. Поверьте, Вы все очень умные и талантливые... А мне надо всего-то новость прочитать.
 
Олег, О! Коллега! Я когда-то спрашивал здесь: "Есть ли на форуме хоть один, кроме меня, кто программирует на чистом Lua"? Никто не отозвался. Оказывается - есть! :smile:

Как это "ничего ужасного"? Ужаснее не придумаешь! Мне нужна пара последних свечей по каждому таймфрейму. Или хотя бы одна, последняя. И таймфреймы-то начинаются аж с 15-минутных. И где взять?

По вопросу ветки: новостями никогда не интересовался, а в этой ветке мне очень понравилось начало:
- Друзья, подскажите пожалуйста можно ли как-то прочитать таблицу новостей QUIK через LUA ?
- Никак.
Страницы: 1 2 След.
Читают тему
Наверх