Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #31  
Старый 27.04.2009, 19:59
Nyctos Kasignete Nyctos Kasignete вне форума
Активный
 
Регистрация: 29.03.2009
Сообщения: 300
Репутация: 94
По умолчанию

Цитата:
Сообщение от одинадцатый
если программа свернута в таскбар(полоску с пуском) - то F9 не обрабатывается
Ну, перед отсылкой сообщения проверяйте: если окно свернуто, то сначала восстановить, а потом послать сообщение.
Код:
if IsIconic(WndHandle) then ShowWindow(WndHandle, SW_RESTORE);
PostMessage(WndHandle, WM_KEYDOWN, VK_F9, 0);

Цитата:
Сообщение от одинадцатый
Может стоит сделать не BM_CLICK, а что то типа BM_MOUSEDOWN а потом BM_MOUSEUP?
Я таких сообщений не знаю. =) Возможно, если в программе прописана реакция не только на "OnClick", но еще на "OnMouseDown" или "OnMouseUp", то нужные команды не выполняются, хотя сказать точно пока не возьмусь. Странно это... Если надо отослать кнопке именно нажатие и опускание кнопки мыши, а не клик, можно запрограммировать так:
Код:
SetCapture(BtnHandle);
SendMessage(BtnHandle, WM_LBUTTONDOWN, 0, 0);
SendMessage(BtnHandle, WM_LBUTTONUP, 0, 0);
ReleaseCapture();
BtnHandle — handle кнопки. При этом сообщение BM_CLICK не отсылается. Его нужно отсылать отдельно. Попробуйте, если желаете.

Цитата:
Сообщение от одинадцатый
А можно как-нибудь выбрать элимент из комбобокс не по тексту, а по индексу?
Код:
SendMessage(ComboBoxHandle, CB_SETCURSEL, Index, 0);
Index — индекс начиная с нуля.

Умолять меня не надо. И так по мере сил своих и возможностей. Я не всемогуща. =)

Регистрировать счет не буду пока. У меня в окне "Терминал" и так есть что считывать (на вкладке "Почтовый ящик"). Я продолжаю подумывать на этот счет. Если что придет на ум, немедленно отпишусь, а сейчас, к сожалению, ничего нового не скажу. Новых идей нет пока.


P.S. Имейте в виду, что тема, из которой я позаимствовала код извлечения содержимого ListView, до сих пор открыта. Если у вас горит этот вопрос, то могу предложить всё же обратиться к автору этого кода. Вероятно, если человек еще посещает форум, то сможет оказать более квалифицированную помощь...

Последний раз редактировалось Nyctos Kasignete, 27.04.2009 в 20:31.
Ответить с цитированием
  #32  
Старый 27.04.2009, 21:47
одинадцатый одинадцатый вне форума
Новичок
 
Регистрация: 16.04.2009
Сообщения: 95
Репутация: 10
По умолчанию

Проблема такая: программа не реагирует на ввод текста в окна через sendmessage, вернее текст в окна записывается, но при нажатии кнопки обработки этого текста программа думает что окна пустые. А может при вводе нового символа а эти окна их одержимое записывается в переменные, и потом из них обрабатывается? И с комбобокс также, элемент выбирается, а действия не происходят, которые должны были произойти при изменении элемента.

Как нажать на кнопку обычного меню?
Ответить с цитированием
  #33  
Старый 28.04.2009, 11:15
Nyctos Kasignete Nyctos Kasignete вне форума
Активный
 
Регистрация: 29.03.2009
Сообщения: 300
Репутация: 94
По умолчанию

По поводу ComboBox. Чтобы выполнялись действия, которые происходят при смене элемента, нужно уведомить об этом изменении само родительское окно, в котором расположен ComboBox. Можно так:
Код:
cbId := GetDlgCtrlId(cbHandle);
SendMessage(cbHandle, CB_SETCURSEL, 2, 0);
SendMessage(MainWndHandle, WM_COMMAND, MakeWParam(cbId, CBN_SELCHANGE), cbHandle);
  • cbId — идентификатор ComboBox'а. Нужен для отправки сообщения WM_COMMAND родительскому окну.
  • cbHandle — дескриптор окна ComboBox'а.
  • MainWndHandle — дескриптор родительского окна, в котором находится ComboBox.

Насчет обычного Edit. Проверяю на том, что мне доступно... Например, нахожу в окне свойств графика вашей программы первый попавшийся Edit, отвечающий за масштаб. Меняю в нем текст:
Код:
const
  NewText = '2.100';
.........
SendMessage(EditHandle, WM_SETTEXT, 0, Integer(@NewText[1]));
Потом нажимаю OK в окне свойств графика, и всё нормально — изменения вступают в силу. Также проверяю на своих программах: просто прописываю реакцию Edit'а на событие OnChange, потом отсылаю ему сообщение WM_SETTEXT, и опять же срабатывает. Не знаю, почему у вас не работает...

Цитата:
Сообщение от одинадцатый
Как нажать на кнопку обычного меню?
так?

Последний раз редактировалось Nyctos Kasignete, 28.04.2009 в 11:18.
Ответить с цитированием
  #34  
Старый 28.04.2009, 17:57
одинадцатый одинадцатый вне форума
Новичок
 
Регистрация: 16.04.2009
Сообщения: 95
Репутация: 10
По умолчанию

Да так, меню заработало)

Тока с едитом проблемы, это такой едит к которому прицеплен spin, он думает что окно так и осталось пустым, может стоит спин поднять на один и опустить?
А как нажать на n строчку листвива правой кнопкой мышки, чтоб вылезло попап меню и нажать в нем на k элемент?
Ответить с цитированием
  #35  
Старый 28.04.2009, 22:03
Nyctos Kasignete Nyctos Kasignete вне форума
Активный
 
Регистрация: 29.03.2009
Сообщения: 300
Репутация: 94
По умолчанию

Что-то я стала отвлекаться...
В общем, пока придумала только как сделать выделенной n-ю строчку в ListView. Опять с громоздкими функциями резервирования памятив чужом процессе. По-другому у меня не получается.
Код:
procedure SelectItemN(ListViewHandle: HWND; N: Integer);
var
  hProcess: THandle;
  dwProcessID: DWORD;
  dwBytesWriten: DWORD;
  plviRemoteLVItem: PLVItem;
  lviRemoteLVItem: LV_ITEM;
begin
  if ListViewHandle = 0 then Exit;
  dwProcessID := 0;

  GetWindowThreadProcessId(ListViewHandle, @dwProcessID);
  if dwProcessID = 0 then Exit;

  hProcess := OpenProcess(PROCESS_ALL_ACCESS, True, dwProcessID);
  if hProcess = 0 then Exit;

  plviRemoteLVItem := VirtualAllocEx(hProcess, nil, SizeOf(LV_ITEM),
                                     MEM_COMMIT or MEM_TOP_DOWN, PAGE_READWRITE);
  if GetLastError <> 0 then Exit;

  ZeroMemory(@lviRemoteLVItem, SizeOf(LV_ITEM));
  with lviRemoteLVItem do
  begin
    mask := LVIF_STATE;
    iItem := N;
    state := LVIS_FOCUSED or LVIS_SELECTED;
    stateMask := LVIS_FOCUSED or LVIS_SELECTED;
  end;

  if not WriteProcessMemory(hProcess, plviRemoteLVItem, @lviRemoteLVItem,
                            SizeOf(LV_ITEM), dwBytesWriten) then Exit;

  SendMessage(ListViewHandle, LVM_SETITEM, 0, Integer(plviRemoteLVItem));

  VirtualFreeEx(hProcess, plviRemoteLVItem, 0, MEM_RELEASE);
  CloseHandle(hProcess);
end;
О контекстных меню пока помолчу. Не работала с ними раньше. Вы уверены, что команда может быть вызвана только из контекстного меню? Если есть аналогичная команда в основном меню, то не лучше ли воспользоваться им? Тем более, что рабочий пример уже имеется.

По поводу SpinEdit. Выяснила, что в Windows эти окна имеют класс msctls_updown32 и при прокрутке чисел родительскому окну отсылается сообщение WM_VSCROLL (если стрелочки вертикальные) или WM_HSCROLL (если горизонтальные). Вот этого сообщения, видимо, и не хватает вашему окну...

Последний раз редактировалось Nyctos Kasignete, 01.05.2009 в 14:58.
Ответить с цитированием
  #36  
Старый 29.04.2009, 09:30
одинадцатый одинадцатый вне форума
Новичок
 
Регистрация: 16.04.2009
Сообщения: 95
Репутация: 10
По умолчанию

Что-то в листвиве не выделяется строчка( и спин тоже не заработал.
Кроме контекстного меню это окно ни как не вызвать.
Как можно узнать, можноли запустить программу как com сервер?
Ответить с цитированием
  #37  
Старый 29.04.2009, 10:58
Nyctos Kasignete Nyctos Kasignete вне форума
Активный
 
Регистрация: 29.03.2009
Сообщения: 300
Репутация: 94
По умолчанию

Цитата:
Сообщение от одинадцатый
Что-то в листвиве не выделяется строчка
А вы опять работаете с нечитабельным ListView в окне Терминал? Если да, то и не будет там выделяться, потому что он видится как пустой вообще... Я проверяла на "нормальных" ListView, в том числе на том, что в окне Обзор рынка. Там всё работает. Со SpinEdit поковыряюсь позже ещё. Только вы напишите, в каком он окне у вас. Если у меня такое есть без регистрации счета, то буду пробовать на нём.
Ответить с цитированием
  #38  
Старый 29.04.2009, 12:34
одинадцатый одинадцатый вне форума
Новичок
 
Регистрация: 16.04.2009
Сообщения: 95
Репутация: 10
По умолчанию

Да опять с нечитабельным)))
Со спином окно - окно которое вылетает при нажатии F9 или новый ордер(стоп лосс и тэйк профит). Чтоб оно вылетело надо зарегится)
Зарегится - процедура занимающая 20 сек. и 2 кб трафика. Вы туда можете не вводить свои подлиные данные, вас это правда ни к чему не обязывает.
Если все же зарегитесь, то запомниет логин и пароль какой вам там выдадут.

Последний раз редактировалось одинадцатый, 29.04.2009 в 12:40.
Ответить с цитированием
  #39  
Старый 29.04.2009, 15:36
Nyctos Kasignete Nyctos Kasignete вне форума
Активный
 
Регистрация: 29.03.2009
Сообщения: 300
Репутация: 94
По умолчанию

А можно как-то перевести эту программу в режим "work offline"? А то когда подключен Интернет, она постоянно кушает трафичек. Хоть и немного наверное, но непрерывно... Меня это очень злит, и я вырубаю прогу!! =(
В общем, по поводу Spin'а. Есть возможность достичь нужной реакции не щелкая по кнопкам вверх-вниз, а просто посылая Edit'у, связанному со Spin'ом, сообщение WM_KEYDOWN, поскольку Edit обрабатывает это сообщение должным образом, в отличие от сообщения WM_SETTEXT. Тот факт, что в Edit вводятся дробные числа заставляет немножко по-разному создавать виртуальные коды клавиш для цифр и для точки-разделителя, но это, думаю, пустячок. Только код чуть-чуть загромождается, но главное — работает.
Вот процедурка, заносящая в нужный Edit со Spin-стрелочками новое значение:
Код:
procedure SetNewValue(EditHandle: HWND; NewValue: Real);
var
  NewValueStr: string;
  i: Integer;
  VKeyCode: Integer;
begin
  NewValueStr := FormatFloat('0.00000', NewValue);
  SendMessage(EditHandle, WM_SETFOCUS, 0, 0);
  SendMessage(EditHandle, EM_SETSEL, 0, -1);
  for i := 1 to Length(NewValueStr) do
  begin
    if NewValueStr[i] = DecimalSeparator then VKeyCode := VK_DECIMAL 
    else VKeyCode := Ord(NewValueStr[i]);
    PostMessage(EditHandle, WM_KEYDOWN, VKeyCode, 0);
  end;
  SendMessage(EditHandle, WM_KILLFOCUS, 0, 0);
end;
Поясняю. Процедура получает параметры:
  • EditHandle — дескриптор Edit'а, сопряженного с объектом Up-Down (он так по-правильному, вроде, называется...)
  • NewValue — новое значение, которое вы хотите установить в Edit'е.
Поскольку там вводится пять знаков после запятой, то поэтому и строка, которую я записываю в Edit, формируется с помощью задания формата '0.00000' в функции FormatFloat. Ну а остальное, кажется, не требует особых разъяснений... Фокус в нужный Edit устанавливается затем, что иначе сообщение WM_KEYDOWN не будет обрабатываться должным образом (обязательно Edit должен иметь фокус ввода клавиатуры). Ну а потом, убираем фокус, чтобы не оставлять ненужных последствий своей деятельности в окне...

Последний раз редактировалось Nyctos Kasignete, 29.04.2009 в 15:43.
Ответить с цитированием
  #40  
Старый 29.04.2009, 19:29
одинадцатый одинадцатый вне форума
Новичок
 
Регистрация: 16.04.2009
Сообщения: 95
Репутация: 10
По умолчанию

Значит все таки зарегились
Спасибо.
Офф-лайново терминал работает тогда, когда вы не залогиноровались.
Просто в пароле добавьте один символ, тогда счет окажется непрвильным и прием катировок прекратится.

Со спином все равно не работает)
Текст вводится, но когда я произвожу транзакцию стоп лосс все равно остается равным 0.00000. Попробуйте сами. Может от того что в едит своей программы я ввожу "," как разделитель(иначе вылетает ошибка неверного дробного значения), а в окне стоп лосса разделителем является "."
Ответить с цитированием
  #41  
Старый 29.04.2009, 19:56
Nyctos Kasignete Nyctos Kasignete вне форума
Активный
 
Регистрация: 29.03.2009
Сообщения: 300
Репутация: 94
По умолчанию

У меня Up-Down точно работает. Там ещё горизонтальные черточки на графике слева ползают в зависимости от того, какое число в Edit'е. Так вот, они переползают на тот уровень, который задаю в параметре процедуры. И разделитель меняла в региональных установках с точки на запятую, и все равно без ошибок...

Не в разделителе дело. Вне зависимости от того, точку или запятую вы будете нажимать в окне Стоп лосс, нарисуется точка — в любом случае. Вот сами и попробуйте.

Последний раз редактировалось Nyctos Kasignete, 29.04.2009 в 20:14.
Ответить с цитированием
  #42  
Старый 29.04.2009, 20:50
одинадцатый одинадцатый вне форума
Новичок
 
Регистрация: 16.04.2009
Сообщения: 95
Репутация: 10
По умолчанию

Извиняюсь, правда работает, первый раз почему то не вышло.
Ответить с цитированием
  #43  
Старый 01.05.2009, 12:56
одинадцатый одинадцатый вне форума
Новичок
 
Регистрация: 16.04.2009
Сообщения: 95
Репутация: 10
По умолчанию

Я помните говорил что без контекстного меню не обойтись - ошибался).
Можно просто даблклик по n строчке и k столбца - так неаверно попроще бдует?
Может знаете как?
И еще как можно узнать является ли программа COM процессом, и как узнать какие ф-ии я могу у нее вызвать?
Ответить с цитированием
  #44  
Старый 01.05.2009, 15:07
Nyctos Kasignete Nyctos Kasignete вне форума
Активный
 
Регистрация: 29.03.2009
Сообщения: 300
Репутация: 94
По умолчанию

Вот так можно отослать двойной клик по нужному Item'у... (Я опять же воспользовалась примером из этой темы...)
Код:
procedure SendDblClick(ListViewHandle: HWND; ItemIndex: Integer);
// ItemIndex — порядковый номер Item'а, начиная с нуля
var
  hProcess: THandle;
  dwProcessID: DWORD;
  dwBytesWriten: DWORD;
  ARect: TRect;
  pRemoteRect: Pointer;
begin
  SelectItemN(ListViewHandle, ItemIndex); // эта процедура описана ранее — в посте #35
  GetWindowThreadProcessId(ListViewHandle, @dwProcessID);
  if dwProcessID = 0 then Exit;
  hProcess := OpenProcess(PROCESS_ALL_ACCESS, True, dwProcessID);
  if hProcess = 0 then Exit;

  pRemoteRect := VirtualAllocEx(hProcess, nil, SizeOf(TRect),
                                MEM_COMMIT or MEM_TOP_DOWN, PAGE_READWRITE);
  if GetLastError <> 0 then Exit;

  ZeroMemory(@ARect, SizeOf(TRect));
  ARect.Left := LVIR_BOUNDS;
  if not WriteProcessMemory(hProcess, pRemoteRect, @ARect,
                            SizeOf(TRect), dwBytesWriten) then Exit;
  SendMessage(ListViewHandle, LVM_GETITEMRECT, ItemIndex, Integer(pRemoteRect));

  ReadProcessMemory(hProcess, pRemoteRect, @ARect, SizeOf(TRect), dwBytesWriten);
  SetCapture(ListViewHandle);
  SendMessage(ListViewHandle, WM_LBUTTONDBLCLK, MK_LBUTTON,
              MakeLParam(ARect.Left + 5, ARect.Top + 5));
  ReleaseCapture();
  VirtualFreeEx(hProcess, pRemoteRect, 0, MEM_RELEASE);
  CloseHandle(hProcess);
end;
Там, где стоят пятерки (при отсылке сообщения WM_LBUTTONDBLCLK), — это так, ориентировочно. Это чтобы "щелкать" двойным кликом не по самой границе, очерчивающей Item, а именно по самому Item'у. =)
Пример использования:
Код:
procedure TForm1.Button1Click(Sender: TObject);
begin
  SendDblClick(Handle_of_ListView, 3); // дважды кликаем по четвертому Item'у
end;

_____________
P.S. Кстати, в сообщении #35 я слегка опечаталась. Раньше в процедуре SelectItemN было так:
Цитата:
Сообщение от Nyctos Kasignete
Код:
state := LVIS_SELECTED or LVIS_SELECTED;
X)) А надо так:
Код:
state := LVIS_FOCUSED or LVIS_SELECTED;
Это чтобы нужный Item не только становился выделенным, но и получал фокус. Но я уже исправила там.

P.P.S. На последний вопрос пусть вам кто-нибудь другой ответит.

Последний раз редактировалось Nyctos Kasignete, 01.05.2009 в 16:42.
Ответить с цитированием
  #45  
Старый 01.05.2009, 17:39
одинадцатый одинадцатый вне форума
Новичок
 
Регистрация: 16.04.2009
Сообщения: 95
Репутация: 10
По умолчанию

расскажите пожалуста еще вот это:
надо чтоб прога на делфи открывала обычный типизтрованный файл(n) для чтения и записи, и при этом переодически n файл открывает для записи и чтения и закрывает программа написанная на другом языке(похожем на С)
с помощью только такого кода(который вызывает библиотеку kernel32.dl)l:
Код:
// константы для функции _lopen
#define OF_READ               0
#define OF_WRITE              1
#define OF_READWRITE          2
#define OF_SHARE_COMPAT       3
#define OF_SHARE_DENY_NONE    4
#define OF_SHARE_DENY_READ    5
#define OF_SHARE_DENY_WRITE   6
#define OF_SHARE_EXCLUSIVE    7

#import "kernel32.dll"
   int _lopen  (string path, int of);
   int _lcreat (string path, int attrib);
   int _llseek (int handle, int offset, int origin);
   int _lread  (int handle, string buffer, int bytes);
   int _lwrite (int handle, string buffer, int bytes);
   int _lclose (int handle);
#import

int t,optime;
// _lopen  : Откpывает указанный файл. Возвpащает: описатель файла.
// _lcreat : Создает указанный файл.   Возвpащает: описатель файла.
// _llseek : Устанавливает указатель в откpытом файле. Возвpащает: 
// новое смещение указателя.
// _lread  : Считывает из откpытого файла указанное число байт. 
// Возвpащает: число считанных байт; 0 - если конец файла.
// _lwrite : Записывает данные из буфеpа в указанный файл. Возвpащает: 
// число записанных байт.
// _lclose : Закpывает указанный файл. Возвpащает: 0.
// В случае неуспешного завеpшения все функции возвращают значение 
// HFILE_ERROR=-1.
 
// path   : Стpока, опpеделяющая путь и имя файла.
// of     : Способ открытия.
// attrib : 0 - чтение или запись; 1 - только чтение; 2 - невидимый или 
// 3 - системный.
// handle : Файловый описатель.
// offset : Число байт, на котоpое пеpемещается указатель.
// origin : Указывает начальную точку и напpавление пеpемещения: 0 - 
// впеpед от начала; 1 - с текущей позиции; 2 - назад от конца файла.
// buffer : Пpинимающий/записываемый буфеp.
// bytes  : Число считываемых байт.
 
// Способы открытия (параметр of):
// int OF_READ            =0; // Открыть файл только для чтения
// int OF_WRITE           =1; // Открыть файл только для записи
// int OF_READWRITE       =2; // Открыть файл в режиме запись/чтение
// int OF_SHARE_COMPAT    =3; // Открывает файл в режиме общего 
// совместного доступа. В этом режиме любой процесс может открыть данный 
// файл любое количество раз. При попытке открыть этот файл в любом другом
// режиме, функция возвращает HFILE_ERROR.
// int OF_SHARE_DENY_NONE =4; // Открывает файл в режиме общего доступа 
// без запрета на чтение/запись другим процессам. При попытке открытия 
// данного файла в режиме OF_SHARE_COMPAT, функция возвращает HFILE_ERROR.
// int OF_SHARE_DENY_READ =5; // Открывает файл в режиме общего доступа с 
// запретом на чтение другим процессам. При попытке открытия данного файла 
// с флагами OF_SHARE_COMPAT и/или OF_READ или OF_READWRITE, функция 
// возвращает HFILE_ERROR.
// int OF_SHARE_DENY_WRITE=6; // Тоже самое, только с запретом на запись.
// int OF_SHARE_EXCLUSIVE =7; // Запрет текущему и другим процессам на 
// доступ к этому файлу в режимах чтения/записи. Файл в этом режиме можно 
// открыть только один раз (текущим процессом). Все остальные попытки 
// открытия файла будут провалены.
главное чтоб при этом не было конфликта ввода, вывода и открытия, закрытия файла.
И как можно осуществить при помощи этой kernel32.dll чтение по строкам(типа readln), всмысле как эта ф-я завется и какие у нее параметры?

Последний раз редактировалось одинадцатый, 01.05.2009 в 18:25.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 01:51.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter