Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > EnumChildWindow() - не находит HWND


Автор: fridkaratel 22.10.2007, 08:07
Имеется программа стороннего разработчика (ПСР). ПСР использует для обработки данные из файла set.ini. Моя программа (МП) подставляет необходимые данные в этот файл.

Чтобы пользователю было удобно и чтобы не светить ПСР, я решил ее запускать через SW_HIDE, и нажимать TToolButton "Start". После нажатия ПСР выполняет действия и выводит статус выполения (заверщения) задачи на TCGauge. Чтобы как-то отображать статус в МП, я думал получать через, скажем, каждые 2 сек сообщения от TCGauge о статусе выполнения.

И сразу возникли две проблемы:
1. Не могу работать с TToolButton, так как не удается получить Handle.
2. Не могу работать с TCGauge, так как не удается получить Handle.

Пробовал через разные сканеры, но результат тот же - этих контролов не видно. Также не видно и TLabel... но это ладно - мне она не нужна...

Как нажать кнопку и получить статус выполнения?

Доп. информация: ПСР не зажата упаковщиками, не зашифрована, можно спокойно декомпилировать и получить нахвания всех процедур, форм и т.п. вещей.

Как быть?

Автор: pandrew 22.10.2007, 09:20
Цитата(fridkaratel @  22.10.2007,  08:07 Найти цитируемый пост)
И сразу возникли две проблемы:
1. Не могу работать с TToolButton, так как не удается получить Handle.
2. Не могу работать с TCGauge, так как не удается получить Handle.
...Также не видно и TLabel...

TToolButton и TLabel наследуется от TGraphicControl и Handle не имеет по определению.
Полагаю, что и TCGauge также.

Автор: fridkaratel 22.10.2007, 09:35
и как же тогда реализовать мне то, что необходимо? :(

Автор: pandrew 22.10.2007, 10:07
1. Придумать другой алгоритм.
2. Обратиться к разработчику ПСР с просьбой добавить необходимую функциональность.
3. Отказаться от данной ПСР.
4. ... smile)

Автор: fridkaratel 22.10.2007, 11:47
я эту тему уже обсудал здесь... 
http://forum.codenet.ru/showthread.php?t=42524

но толку это не принесло...

можно почитать и предложить свои версии о том, что дальше делать...

Автор: pandrew 22.10.2007, 12:43
Вы пытаетесь управлять чужим софтом, который для этого не предназначен. Можно полностью имитировать действия юзера: позиционирование курсора, клики на кнопках и т.д. Для считывания показаний Gauge можно делать скриншоты и анализировать картинку, хоть через персептроны.
Однако, самый дешевый способ - обратиться к разработчику ПСР с просьбой о доработке, например добавить реализацию интерфейса COM.
Либо реализовать всю функциональность заново.

Автор: fridkaratel 22.10.2007, 13:20
я думал про подключаемую dll... но толку то нет - как получить значение TCGauge? кнопка TToolButton - фиг с ней, а вот как получить статус?

Была еще такая идея - на примере ArtMoney - искать данные в памяти процесса... скорей всего, данные о прогрессе имеют постоянный адрес, так как смысла делать его динамическим нет...

Итак, какие варианты?

Автор: dumb 22.10.2007, 14:15
Цитата(fridkaratel @  22.10.2007,  14:20 Найти цитируемый пост)
Итак, какие варианты? 
учи олбанский - либо китайский, либо ассемблер... smile

Автор: fridkaratel 22.10.2007, 15:16
короче, как я понял - самы надежный и лучший выход из ситуации - на асме встроить доп. функционал в программу... блин, капец... :(

Автор: 586 22.10.2007, 15:37
Цитата(fridkaratel @  22.10.2007,  14:20 Найти цитируемый пост)
я думал про подключаемую dll... 

ПСР написана на Delphi или Builder'e? Если на Builder'e, с помощью tdump посмотри таблицу экспорта exe-шника ПСР.
Цитата
Exports from Project1.exe
  5 exported name(s), 5 export addresse(s).  Ordinal base is 1.
  Sorted by Name:
    RVA      Ord. Hint Name
    -------- ---- ---- ----
    00001EF4    3 0000 __linkproc__ Unit1::Finalize
    00001EE4    2 0001 __linkproc__ Unit1::Initialize
    000575D8    5 0002 _Form1
    00001295    1 0003 __GetExceptDLLinfo
    00056098    4 0004 ___CPPdebugHook

и в DLL можно сделать такой трюк:
Код
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  TForm *f=*(TForm**)GetProcAddress(GetModuleHandle(NULL), "_Form1");
  if (f) {
    TLabel *l=(TLabel*)f->FindComponent("Label1");  // найти можно любой компонент
    if(l) l->Caption="Hello world";
    else MessageBoxA(NULL, "Label1 is not accessible", 0, 16);
  }
  else MessageBoxA(NULL, "Form is not accessible", 0, 16);
}

Автор: fridkaratel 22.10.2007, 16:18
программа написана на Borland C++ Builder 6.

586, то, что ты предложил уже можно пробовать реализовывать? или еще подождать? smile

Автор: 586 22.10.2007, 16:23
Цитата(fridkaratel @  22.10.2007,  17:18 Найти цитируемый пост)
что ты предложил уже можно пробовать реализовывать? или еще подождать

Посмотри таблицу экспорта того приложения, или сюда выложи. Может там и нет ничего...

Автор: fridkaratel 22.10.2007, 17:43
хех... интересная задачка smile

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

PS: но tdump я нашел smile также просмотрел через PEBrowse Pro exe-файлик и как бы нашел там эту таблицу: Sections->.text ... что с ней делать, а может и не с ней?

Автор: 586 22.10.2007, 18:22
1.   Выполнить -> cmd.exe
1.1 mode con lines=9999       // если не хватает места в консоли
2.   tdump C:\programs\app.exe
3.   В самом низу будут выписаны ресурсы, выше - таблица экспорта (см. код выше)

Цитата(fridkaratel @  22.10.2007,  18:43 Найти цитируемый пост)
нашел там эту таблицу: Sections->.text 

это таблица секций, а не экспорта

Автор: dumb 22.10.2007, 18:33
или просто
Код
tdump -ee proga.exe
 smile 

Автор: fridkaratel 22.10.2007, 18:46
блин... я такую же таблицу видел в дебаггере, когда пытался найти таблицу экспорта... smile

и еще - у меня ошибка выдавалась, мол не могу открыть файл... я думал-думал, а оказалось, что я просто директорию не поменял - по умолчанию при cmd стоит ведь "Мои документы", а программу я положил в C:\1... капец, короче... уже скарились мозги вконец...  smile 

Так, вот выкладываю таблицу...
Цитата

Turbo Dump  Version 5.0.16.12 Copyright © 1988, 2000 Inprise Corporation
                      Display of File FT.EXE

EXPORT ord:0048='__tpdsc__ TCCalendar'
EXPORT ord:0138='__tpdsc__ Cspin::TCSpinEdit'
EXPORT ord:0172='__tpdsc__ TPerformanceGraph'
EXPORT ord:0140='__tpdsc__ Cspin::TCSpinButton'
EXPORT ord:0137='__tpdsc__ Cspin::TTimerSpeedButton'
EXPORT ord:0070='__tpdsc__ Cdiroutl::TCDirectoryOutline'
EXPORT ord:0091='__tpdsc__ TCGauge'
EXPORT ord:0203='__tpdsc__ TTrayIcon'
EXPORT ord:0013='__linkproc__ About::Finalize'
EXPORT ord:0012='__linkproc__ About::Initialize'
EXPORT ord:0051='__linkproc__ Ccalendr::Finalize'
EXPORT ord:0050='__linkproc__ Ccalendr::Initialize'
EXPORT ord:0072='__linkproc__ Cdiroutl::Finalize'
EXPORT ord:0071='__linkproc__ Cdiroutl::Initialize'
EXPORT ord:0093='__linkproc__ Cgauges::Finalize'
EXPORT ord:0092='__linkproc__ Cgauges::Initialize'
EXPORT ord:0144='__linkproc__ Cspin::Finalize'
EXPORT ord:0143='__linkproc__ Cspin::Initialize'
EXPORT ord:0005='__linkproc__ Da_option::Finalize'
EXPORT ord:0004='__linkproc__ Da_option::Initialize'
EXPORT ord:0017='__linkproc__ Dl_go::Finalize'
EXPORT ord:0016='__linkproc__ Dl_go::Initialize'
EXPORT ord:0009='__linkproc__ Ext_mem1::Finalize'
EXPORT ord:0008='__linkproc__ Ext_mem1::Initialize'
EXPORT ord:0023='__linkproc__ Frm_bootromstartcmdretry::Finalize'
EXPORT ord:0022='__linkproc__ Frm_bootromstartcmdretry::Initialize'
EXPORT ord:0025='__linkproc__ Frm_com_option::Finalize'
EXPORT ord:0024='__linkproc__ Frm_com_option::Initialize'
EXPORT ord:0021='__linkproc__ Frm_formatoption::Finalize'
EXPORT ord:0020='__linkproc__ Frm_formatoption::Initialize'
EXPORT ord:0003='__linkproc__ Main::Finalize'
EXPORT ord:0002='__linkproc__ Main::Initialize'
EXPORT ord:0011='__linkproc__ Ok_wnd::Finalize'
EXPORT ord:0010='__linkproc__ Ok_wnd::Initialize'
EXPORT ord:0174='__linkproc__ Perfgrap::Finalize'
EXPORT ord:0173='__linkproc__ Perfgrap::Initialize'
EXPORT ord:0019='__linkproc__ Rb_go::Finalize'
EXPORT ord:0018='__linkproc__ Rb_go::Initialize'
EXPORT ord:0015='__linkproc__ Rb_option::Finalize'
EXPORT ord:0014='__linkproc__ Rb_option::Initialize'
EXPORT ord:0007='__linkproc__ Tboot_1::Finalize'
EXPORT ord:0006='__linkproc__ Tboot_1::Initialize'
EXPORT ord:0205='__linkproc__ Trayicon::Finalize'
EXPORT ord:0204='__linkproc__ Trayicon::Initialize'
EXPORT ord:0209='Cdiroutl::TCDirectoryOutline::'
EXPORT ord:0052='__fastcall Cdiroutl::TCDirectoryOutline::TCDirectoryOutline(Classes::TComponent *)'
EXPORT ord:0208='Cdiroutl::TCDirectoryOutline::APointer'
EXPORT ord:0053='__fastcall Cdiroutl::TCDirectoryOutline::AssignCaseProc()'
EXPORT ord:0054='__fastcall Cdiroutl::TCDirectoryOutline::BuildOneLevel(long)'
EXPORT ord:0056='__fastcall Cdiroutl::TCDirectoryOutline::BuildSubTree(long)'
EXPORT ord:0055='__fastcall Cdiroutl::TCDirectoryOutline::BuildTree()'
EXPORT ord:0057='__fastcall Cdiroutl::TCDirectoryOutline::Change()'
EXPORT ord:0058='__fastcall Cdiroutl::TCDirectoryOutline::Click()'
EXPORT ord:0059='__fastcall Cdiroutl::TCDirectoryOutline::CreateWnd()'
EXPORT ord:0067='Cdiroutl::TCDirectoryOutline::CurDir()'
EXPORT ord:0065='__fastcall Cdiroutl::TCDirectoryOutline::DriveToInt(char)'
EXPORT ord:0060='__fastcall Cdiroutl::TCDirectoryOutline::Expand(int)'
EXPORT ord:0062='__fastcall Cdiroutl::TCDirectoryOutline::ForceCase(const System::AnsiString&)'
EXPORT ord:0068='__fastcall Cdiroutl::TCDirectoryOutline::GetChildNamed(const System::AnsiString&, long)'
EXPORT ord:0227='Cdiroutl::TCDirectoryOutline::InvalidIndex'
EXPORT ord:0061='__fastcall Cdiroutl::TCDirectoryOutline::Loaded()'
EXPORT ord:0228='Cdiroutl::TCDirectoryOutline::RootIndex'
EXPORT ord:0063='__fastcall Cdiroutl::TCDirectoryOutline::SetDirectory(System::AnsiString)'
EXPORT ord:0064='__fastcall Cdiroutl::TCDirectoryOutline::SetDrive(char)'
EXPORT ord:0066='__fastcall Cdiroutl::TCDirectoryOutline::SetTextCase(Cdiroutl::TTextCase)'
EXPORT ord:0069='__fastcall Cdiroutl::TCDirectoryOutline::WalkTree(const System::AnsiString&)'
EXPORT ord:0213='Cspin::TCSpinButton::'
EXPORT ord:0094='__fastcall Cspin::TCSpinButton::TCSpinButton(Classes::TComponent *)'
EXPORT ord:0142='__fastcall Cspin::TCSpinButton::~TCSpinButton()'
EXPORT ord:0096='__fastcall Cspin::TCSpinButton::AdjustSize(int&, int&)'
EXPORT ord:0103='__fastcall Cspin::TCSpinButton::BtnClick(System::TObject *)'
EXPORT ord:0102='__fastcall Cspin::TCSpinButton::BtnMouseDown(System::TObject *, Controls::TMouseButton, System::Set<Classes::Classes__1, 0, 6>, int, int)'
EXPORT ord:0095='__fastcall Cspin::TCSpinButton::CreateButton()'
EXPORT ord:0141='__fastcall Cspin::TCSpinButton::Dispatch(void *)'
EXPORT ord:0109='__fastcall Cspin::TCSpinButton::GetDownGlyph()'
EXPORT ord:0107='__fastcall Cspin::TCSpinButton::GetUpGlyph()'
EXPORT ord:0101='__fastcall Cspin::TCSpinButton::KeyDown(unsigned short&, System::Set<Classes::Classes__1, 0, 6>)'
EXPORT ord:0106='__fastcall Cspin::TCSpinButton::Loaded()'
EXPORT ord:0097='__fastcall Cspin::TCSpinButton::SetBounds(int, int, int, int)'
EXPORT ord:0110='__fastcall Cspin::TCSpinButton::SetDownGlyph(Graphics::TBitmap *)'
EXPORT ord:0104='__fastcall Cspin::TCSpinButton::SetFocusBtn(Cspin::TTimerSpeedButton *)'
EXPORT ord:0108='__fastcall Cspin::TCSpinButton::SetUpGlyph(Graphics::TBitmap *)'
EXPORT ord:0105='__fastcall Cspin::TCSpinButton::WMGetDlgCode(Messages::TWMNoParams&)'
EXPORT ord:0100='__fastcall Cspin::TCSpinButton::WMKillFocus(Messages::TWMKillFocus&)'
EXPORT ord:0099='__fastcall Cspin::TCSpinButton::WMSetFocus(Messages::TWMSetFocus&)'
EXPORT ord:0098='__fastcall Cspin::TCSpinButton::WMSize(Messages::TWMSize&)'
EXPORT ord:0212='Cspin::TCSpinEdit::'
EXPORT ord:0111='__fastcall Cspin::TCSpinEdit::TCSpinEdit(Classes::TComponent *)'
EXPORT ord:0112='__fastcall Cspin::TCSpinEdit::~TCSpinEdit()'
EXPORT ord:0130='__fastcall Cspin::TCSpinEdit::CMEnter(Messages::TWMNoParams&)'
EXPORT ord:0126='__fastcall Cspin::TCSpinEdit::CMExit(Messages::TWMNoParams&)'
EXPORT ord:0129='__fastcall Cspin::TCSpinEdit::CheckValue(long)'
EXPORT ord:0117='__fastcall Cspin::TCSpinEdit::CreateParams(Controls::TCreateParams&)'
EXPORT ord:0118='__fastcall Cspin::TCSpinEdit::CreateWnd()'
EXPORT ord:0139='__fastcall Cspin::TCSpinEdit::Dispatch(void *)'
EXPORT ord:0123='__fastcall Cspin::TCSpinEdit::DownClick(System::TObject *)'
EXPORT ord:0113='__fastcall Cspin::TCSpinEdit::GetChildren(void __fastcall __closure(*)(Classes::TComponent *), Classes::TComponent *)'
EXPORT ord:0121='__fastcall Cspin::TCSpinEdit::GetMinHeight()'
EXPORT ord:0127='__fastcall Cspin::TCSpinEdit::GetValue()'
EXPORT ord:0116='__fastcall Cspin::TCSpinEdit::IsValidChar(char)'
EXPORT ord:0114='__fastcall Cspin::TCSpinEdit::KeyDown(unsigned short&, System::Set<Classes::Classes__1, 0, 6>)'
EXPORT ord:0115='__fastcall Cspin::TCSpinEdit::KeyPress(char&)'
EXPORT ord:0119='__fastcall Cspin::TCSpinEdit::SetEditRect()'
EXPORT ord:0128='__fastcall Cspin::TCSpinEdit::SetValue(long)'
EXPORT ord:0122='__fastcall Cspin::TCSpinEdit::UpClick(System::TObject *)'
EXPORT ord:0125='__fastcall Cspin::TCSpinEdit::WMCut(Messages::TWMNoParams&)'
EXPORT ord:0124='__fastcall Cspin::TCSpinEdit::WMPaste(Messages::TWMNoParams&)'
EXPORT ord:0120='__fastcall Cspin::TCSpinEdit::WMSize(Messages::TWMSize&)'
EXPORT ord:0211='Cspin::TTimerSpeedButton::'
EXPORT ord:0131='__fastcall Cspin::TTimerSpeedButton::TTimerSpeedButton(Classes::TComponent *)'
EXPORT ord:0132='__fastcall Cspin::TTimerSpeedButton::~TTimerSpeedButton()'
EXPORT ord:0133='__fastcall Cspin::TTimerSpeedButton::MouseDown(Controls::TMouseButton, System::Set<Classes::Classes__1, 0, 6>, int, int)'
EXPORT ord:0134='__fastcall Cspin::TTimerSpeedButton::MouseUp(Controls::TMouseButton, System::Set<Classes::Classes__1, 0, 6>, int, int)'
EXPORT ord:0136='__fastcall Cspin::TTimerSpeedButton::Paint()'
EXPORT ord:0135='__fastcall Cspin::TTimerSpeedButton::TimerExpired(System::TObject *)'
EXPORT ord:0207='TCCalendar::'
EXPORT ord:0026='__fastcall TCCalendar::TCCalendar(Classes::TComponent *)'
EXPORT ord:0027='__fastcall TCCalendar::Change()'
EXPORT ord:0041='__fastcall TCCalendar::ChangeMonth(int)'
EXPORT ord:0028='__fastcall TCCalendar::Click()'
EXPORT ord:0030='__fastcall TCCalendar::DaysPerMonth(int, int)'
EXPORT ord:0031='__fastcall TCCalendar::DaysThisMonth()'
EXPORT ord:0049='__fastcall TCCalendar::Dispatch(void *)'
EXPORT ord:0032='__fastcall TCCalendar::DrawCell(int, int, const Types::TRect&, System::Set<Grids::Grids__3, 0, 2>)'
EXPORT ord:0033='__fastcall TCCalendar::GetCellText(int, int)'
EXPORT ord:0037='__fastcall TCCalendar::GetDateElement(int)'
EXPORT ord:0029='__fastcall TCCalendar::IsLeapYear(int)'
EXPORT ord:0043='__fastcall TCCalendar::NextMonth()'
EXPORT ord:0044='__fastcall TCCalendar::NextYear()'
EXPORT ord:0042='__fastcall TCCalendar::PrevMonth()'
EXPORT ord:0045='__fastcall TCCalendar::PrevYear()'
EXPORT ord:0035='__fastcall TCCalendar::SeTCCalendarDate(System::TDateTime)'
EXPORT ord:0034='__fastcall TCCalendar::SelectCell(int, int)'
EXPORT ord:0038='__fastcall TCCalendar::SetDateElement(int, int)'
EXPORT ord:0039='__fastcall TCCalendar::SetStartOfWeek(short)'
EXPORT ord:0040='__fastcall TCCalendar::SetUseCurrentDate(bool)'
EXPORT ord:0036='__fastcall TCCalendar::StoreCalendarDate()'
EXPORT ord:0046='__fastcall TCCalendar::UpdateCalendar()'
EXPORT ord:0047='__fastcall TCCalendar::WMSize(Messages::TWMSize&)'
EXPORT ord:0210='TCGauge::'
EXPORT ord:0073='__fastcall TCGauge::TCGauge(Classes::TComponent *)'
EXPORT ord:0090='__fastcall TCGauge::AddProgress(long)'
EXPORT ord:0074='__fastcall TCGauge::GetPercentDone()'
EXPORT ord:0075='__fastcall TCGauge::Paint()'
EXPORT ord:0079='__fastcall TCGauge::PaintAsBar(Graphics::TBitmap *, const Types::TRect&)'
EXPORT ord:0081='__fastcall TCGauge::PaintAsNeedle(Graphics::TBitmap *, const Types::TRect&)'
EXPORT ord:0078='__fastcall TCGauge::PaintAsNothing(Graphics::TBitmap *, const Types::TRect&)'
EXPORT ord:0080='__fastcall TCGauge::PaintAsPie(Graphics::TBitmap *, const Types::TRect&)'
EXPORT ord:0077='__fastcall TCGauge::PaintAsText(Graphics::TBitmap *, const Types::TRect&)'
EXPORT ord:0076='__fastcall TCGauge::PaintBackground(Graphics::TBitmap *)'
EXPORT ord:0082='__fastcall TCGauge::SeTCGaugeKind(TCGaugeKind)'
EXPORT ord:0086='__fastcall TCGauge::SetBackColor(Graphics::TColor)'
EXPORT ord:0084='__fastcall TCGauge::SetBorderStyle(Forms::TFormBorderStyle)'
EXPORT ord:0085='__fastcall TCGauge::SetForeColor(Graphics::TColor)'
EXPORT ord:0088='__fastcall TCGauge::SetMaxValue(long)'
EXPORT ord:0087='__fastcall TCGauge::SetMinValue(long)'
EXPORT ord:0089='__fastcall TCGauge::SetProgress(long)'
EXPORT ord:0083='__fastcall TCGauge::SetShowText(bool)'
EXPORT ord:0214='TPerformanceGraph::'
EXPORT ord:0145='__fastcall TPerformanceGraph::TPerformanceGraph(Classes::TComponent *)'
EXPORT ord:0147='__fastcall TPerformanceGraph::~TPerformanceGraph()'
EXPORT ord:0162='__fastcall TPerformanceGraph::DataPoint(Graphics::TColor, long)'
EXPORT ord:0164='__fastcall TPerformanceGraph::DisplayPoints(long)'
EXPORT ord:0167='__fastcall TPerformanceGraph::FirstY()'
EXPORT ord:0146='__fastcall TPerformanceGraph::GetBandCount()'
EXPORT ord:0148='__fastcall TPerformanceGraph::Initialize(long)'
EXPORT ord:0165='__fastcall TPerformanceGraph::LastY(int)'
EXPORT ord:0168='__fastcall TPerformanceGraph::NextY(int)'
EXPORT ord:0149='__fastcall TPerformanceGraph::Paint()'
EXPORT ord:0160='__fastcall TPerformanceGraph::PaintBar(Graphics::TColor, long, long)'
EXPORT ord:0161='__fastcall TPerformanceGraph::PaintLine(Graphics::TColor, long, long)'
EXPORT ord:0166='__fastcall TPerformanceGraph::ReallocHistory()'
EXPORT ord:0171='__fastcall TPerformanceGraph::Replay()'
EXPORT ord:0156='__fastcall TPerformanceGraph::RoundUp(long, long)'
EXPORT ord:0163='__fastcall TPerformanceGraph::ScrollGraph()'
EXPORT ord:0152='__fastcall TPerformanceGraph::SetBackColor(Graphics::TColor)'
EXPORT ord:0151='__fastcall TPerformanceGraph::SetForeColor(Graphics::TColor)'
EXPORT ord:0157='__fastcall TPerformanceGraph::SetGradient(long)'
EXPORT ord:0150='__fastcall TPerformanceGraph::SetGraphKind(TGraphKind)'
EXPORT ord:0153='__fastcall TPerformanceGraph::SetGridSize(long)'
EXPORT ord:0158='__fastcall TPerformanceGraph::SetGridlines(bool)'
EXPORT ord:0159='__fastcall TPerformanceGraph::SetPenWidth(long)'
EXPORT ord:0155='__fastcall TPerformanceGraph::SetScale(long)'
EXPORT ord:0154='__fastcall TPerformanceGraph::SetStepSize(long)'
EXPORT ord:0170='__fastcall TPerformanceGraph::ShiftY()'
EXPORT ord:0169='__fastcall TPerformanceGraph::Update()'
EXPORT ord:0215='TTrayIcon::'
EXPORT ord:0175='__fastcall TTrayIcon::TTrayIcon(Classes::TComponent *)'
EXPORT ord:0176='__fastcall TTrayIcon::~TTrayIcon()'
EXPORT ord:0200='__fastcall TTrayIcon::ApplicationHookProc(Messages::TMessage&)'
EXPORT ord:0190='__fastcall TTrayIcon::DoClick()'
EXPORT ord:0191='__fastcall TTrayIcon::DoDblClick()'
EXPORT ord:0188='__fastcall TTrayIcon::DoMessage(Messages::TMessage&)'
EXPORT ord:0193='__fastcall TTrayIcon::DoMouseDown(Controls::TMouseButton, System::Set<Classes::Classes__1, 0, 6>, int, int)'
EXPORT ord:0192='__fastcall TTrayIcon::DoMouseMove(System::Set<Classes::Classes__1, 0, 6>, int, int)'
EXPORT ord:0194='__fastcall TTrayIcon::DoMouseUp(Controls::TMouseButton, System::Set<Classes::Classes__1, 0, 6>, int, int)'
EXPORT ord:0195='__fastcall TTrayIcon::DoOnAnimate(System::TObject *)'
EXPORT ord:0186='__fastcall TTrayIcon::EndSession()'
EXPORT ord:0184='__fastcall TTrayIcon::GetAnimate()'
EXPORT ord:0182='__fastcall TTrayIcon::GetAnimateInterval()'
EXPORT ord:0202='__fastcall TTrayIcon::GetHandle()'
EXPORT ord:0178='__fastcall TTrayIcon::Loaded()'
EXPORT ord:0196='__fastcall TTrayIcon::Minimize()'
EXPORT ord:0177='__fastcall TTrayIcon::Notification(Classes::TComponent *, Classes::TOperation)'
EXPORT ord:0197='__fastcall TTrayIcon::Restore()'
EXPORT ord:0185='__fastcall TTrayIcon::SetAnimate(bool)'
EXPORT ord:0183='__fastcall TTrayIcon::SetAnimateInterval(int)'
EXPORT ord:0201='__fastcall TTrayIcon::SetDefaultIcon()'
EXPORT ord:0181='__fastcall TTrayIcon::SetHide(bool)'
EXPORT ord:0180='__fastcall TTrayIcon::SetHint(System::AnsiString)'
EXPORT ord:0199='__fastcall TTrayIcon::SetIconIndex(int)'
EXPORT ord:0179='__fastcall TTrayIcon::SetVisible(bool)'
EXPORT ord:0187='TTrayIcon::ShiftState()'
EXPORT ord:0189='__fastcall TTrayIcon::ShowMenu()'
EXPORT ord:0198='__fastcall TTrayIcon::Update()'
EXPORT ord:0226='_COM_Option'
EXPORT ord:0220='_Form_About'
EXPORT ord:0217='_Form_DA_Option'
EXPORT ord:0222='_Form_DL_GO'
EXPORT ord:0219='_Form_OK'
EXPORT ord:0223='_Form_RB_GO'
EXPORT ord:0221='_Form_RB_Option'
EXPORT ord:0224='_FormatOption'
EXPORT ord:0216='_MainForm'
EXPORT ord:0001='__GetExceptDLLinfo'
EXPORT ord:0206='___CPPdebugHook'
EXPORT ord:0218='_ext_mem1Form'
EXPORT ord:0225='_frm_BromStartCmdRetry'

Автор: dumb 22.10.2007, 19:32
такое ощущение, что это программа, демонстрирующая возможности компонентов с закладки Samples...   у этой проги полезная функциональность есть вообще? smile

Автор: fridkaratel 22.10.2007, 19:36
smile да. У меня даже от нее исходники есть, правда 2001 года... от второй версии, а эта уже 4-й... smile

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

если есть необходимость  - могу дать ссылку для скачивания программы...

Автор: dumb 22.10.2007, 19:46
Цитата(fridkaratel @  22.10.2007,  20:36 Найти цитируемый пост)
если есть необходимость
необходимость может быть только у тебя. у нас же - только любопытство и желание/нежелание помочь. smile

Цитата(fridkaratel @  22.10.2007,  20:36 Найти цитируемый пост)
могу дать ссылку для скачивания программы...
давно надо было.

Автор: 586 22.10.2007, 19:58
DLL
Код
#include <windows.h>
#include <vcl.h>
#include "CGAUGES.h"

#pragma argsused

// этими объектами можно управлять, как своими
// при изменении свойств объектов могут возникнуть проблемы с синхронизацией
// при чтении должно быть все нормально
TForm *MainForm=NULL;
TCGauge *CGauge1=NULL;

void Init()
{
  TForm **pForm=(TForm**)GetProcAddress(GetModuleHandle(NULL), "_MainForm");
  if(pForm==NULL)
  {
    /* ERROR: export not found */
  }
  else
  {
    MainForm=*pForm;
    if(MainForm==NULL)
    {
      /* ERROR: form is not accessible */
    }
    else
    {
      CGauge1=(TCGauge*)MainForm->FindComponent("CGauge1");
      if(CGauge1==NULL)
      {
        /* ERROR: CGauge not found */
      }
      else
      {
        CGauge1->Progress=50;  // for test
      }
    }
  }
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpvReserved)
{
    switch(dwReason)
    {
    case DLL_PROCESS_ATTACH:
        Init();
        break;
    }

    return 1;
}


программа-стартер
Код
#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------

HMODULE hRemoteModule=NULL;

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  STARTUPINFO si;
  PROCESS_INFORMATION pi;

  bool bSuccess=false;

  memset(&si, 0, sizeof(si));
  si.cb=sizeof(si);

  if(!CreateProcess(NULL, "..\\__test2\\project1.exe", 0, 0, FALSE, 0, 0, 0, &si, &pi))
  {
    ShowMessage(SysErrorMessage(GetLastError()));
  }
  else
  {
    DWORD res=WaitForInputIdle(pi.hProcess, 10000);    // 10 secs
    if(res==WAIT_TIMEOUT)
    {
      if(MessageBoxA(Handle, "Превышен предел ожидания. Уничтожить процесс?", 0, MB_YESNO | 16)==IDYES)
        TerminateProcess(pi.hProcess, 0);
    }
    else
    {
      String DllPath=ExtractFilePath(ExcludeTrailingBackslash(ExtractFilePath(Application->ExeName)));
      DllPath+="\\__test1\\project2.dll";
      LPVOID p=VirtualAllocEx(pi.hProcess, 0, DllPath.Length()+1, MEM_COMMIT, PAGE_READWRITE);
      if(!p)
      {
        ShowMessage("Can't Write Memory To Process: "+SysErrorMessage(GetLastError()));
      }
      else
      {
        if(!WriteProcessMemory(pi.hProcess, p, DllPath.c_str(), DllPath.Length()+1, NULL))
        {
           ShowMessage("Can't write to process memory");
        }
        else
        {
          FARPROC fp=GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
          if(!fp)
          {
            ShowMessage("Can't get address of kernel32.dll!LoadLibraryA");
          }
          else
          {
            HANDLE hThread=CreateRemoteThread(pi.hProcess, 0, 0, (LPTHREAD_START_ROUTINE)fp, (LPVOID)p, 0, NULL);
            if(!hThread)
            {
              ShowMessage("Can't create remote thread: "+SysErrorMessage(GetLastError()));
            }
            else
            {
              res=WaitForSingleObject(hThread, 10000);  // wait 10 secs

              if(res==WAIT_TIMEOUT)
              {
                if(MessageBoxA(Handle, "Поток завис. Завершить его?", 0, 16 | MB_YESNO)==IDYES)
                {
                  TerminateThread(hThread, 0);
                }
              }

              GetExitCodeThread(hThread, (LPDWORD)&hRemoteModule);
              if(hRemoteModule) bSuccess=true;
              else ShowMessage("Инициализация DLL в удалённом процессе завершена с ошибкой");
              CloseHandle(hThread);
            }  // hThread
          } // (!fp)
        } // write process memory
        VirtualFreeEx(pi.hProcess, p, DllPath.Length()+1, MEM_FREE);
      }  // virtual alloc
    }  // WaitForInputIdle(...) == WAIT_TIMEOUT

    CloseHandle(pi.hThread);
    CloseHandle(pi.hProcess);
  } // CreateProcess

  if(bSuccess) ShowMessage("Операция успешно завершена :)");
}

Автор: fridkaratel 23.10.2007, 04:18
я могу дать и исходники тоже... ;) просто смысла не вижу особого - там все, практически, по-другому, версия ведь аж 2.0... smile

блин... не могу теперь ссылку на программу найти smile как быть? куда можно закачать? а то малький лимит размера прикрепленного файла... а он в архиве весит ~400 Кб...

Добавлено через 10 минут и 53 секунды
вот ссылка для скачивания с другого форума:
http://unlock.in.ua/forum/showpost.php?p=5&postcount=1

вот еще есть, правда версию не знаю:
http://siriust.ru/index_p.php?fid=2916

вот вроде как самая последняя версия... ;) Лучше ее скачать, а потом уже остальные, если  желание будет smile
http://profimobile.ru/list-files/view.php?fid=3594&dir_id=82

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

Автор: 586 23.10.2007, 07:53
Цитата(fridkaratel @  23.10.2007,  05:18 Найти цитируемый пост)
это для ознакомления, чтобы с чего-то начать

да

Автор: fridkaratel 23.10.2007, 13:10
есть проблема... создаю New Application -> Other -> DLL Wizard, вставляю код в юнит, компилирую, потом создаю стартер и его запускаю... при нажатии на кнопку запускается программа, но стартер выдает ошибку: "Инициализация DLL в удалённом процессе завершена с ошибкой".

1. Правильно ли я создаю DLL? просто у тебя BOOL WINAPI DllMain, а у меня int WINAPI DllMain
2. Что делать?

Автор: dumb 23.10.2007, 14:08
Цитата(fridkaratel @  23.10.2007,  14:10 Найти цитируемый пост)
Что делать?
судя по тому, что ты не смог разобраться с этим примером(а надо было лишь соблюсти правильность имен .exe/.dll), то тебе остается только просить кого-то сделать готовый механизм, так как этот пример нужно еще обработать напильником - добавить, как минимум, возможность взаимодействия(ipc) между dll и запускающей программой.

Автор: fridkaratel 23.10.2007, 14:22
в том то и дело, что я изменил имена всех программ и подключаемого DLL

Стартер - starter.exe
Модуль DLL - control.dll
Программа, которой необходимо управлять - ft.exe

Все это я поместил в папку C:\1, соответственно, измнил все пути на этот, чтобы не делать ExtractFilePath и т.п. вещей, и чтобы не запутаться в путях...

Но в итоге запускается по нажатию кнопки только программа, а модуль не подключается... я даже просмотрел список DLL, использующихся программой ft.exe
Выдается сообщение, которое я написал выше...

Так как быть ? smile

PS: а ничего страшного, если я вместо int WINAPI MAIN поставил твое значение - BOOL WINAPI MAIN?

Автор: 586 23.10.2007, 15:50
Цитата(fridkaratel @  23.10.2007,  15:22 Найти цитируемый пост)
 а ничего страшного, если я вместо int WINAPI MAIN поставил твое значение - BOOL WINAPI MAIN? 

норм. Это одно и тоже.
Цитата(586 @  22.10.2007,  20:58 Найти цитируемый пост)
GetExitCodeThread(hThread, (LPDWORD)&hRemoteModule);
              if(hRemoteModule) bSuccess=true;
              else ShowMessage("Инициализация DLL в удалённом процессе завершена с ошибкой");

Тут идёт проверка, что вернула фунуция LoadLibraryA. Причина ошибки скорее из-за:
1. указан не правильный путь
2. DllMain вернула 0.


Автор: fridkaratel 23.10.2007, 16:51
проблема была в строке:
String DllPath=ExtractFilePath(ExcludeTrailingBackslash(ExtractFilePath(Application->ExeName)));

я сомневался и хотел почистить ее на c:\1, но решил, что тут идет какое-то специальное вычисление пути...
оказалось, что просто удаляет последний путь, то есть вместо c:\1\2 напишет c:\1.. smile

Все ок - работает ;)

Спасибо...

Только почему при наведении курсора на кнопку закрытия окна появляются сообщения "ОК"?

И как отслеживать изменение TCGauge?

PS: как я рад smile уже получается управлять, причем неплохо управлять... уже и на этом большое спасибо, жаль прав нет плюсики ставить, т.е. благодарить...

Автор: fridkaratel 24.10.2007, 05:17
так, теперь необходимо не установить какие-либо параметры контролов, а получить при обновлении... какие здесь будут варианты? создать TTimer, который будет через определенное время посылать команды МП или создать TApplicationEvent, который будет перехватывать все сообщения? может есть еще что сделать можно?

PS: чувствую, что конец уже не за горами - и тема будет разобрана полностью 

Автор: 586 24.10.2007, 21:20
А в чём конкретно проблемы? В динамическом создании TApplicationEvents? TTimer?
Я не знаю, как отследить изменение TCGauge. В exe-шнике экспортируется ф-ция __fastcall SetProgress(long). Можно попробовать её перехватить. 
Цитата(fridkaratel @  24.10.2007,  06:17 Найти цитируемый пост)
 или создать TApplicationEvent, который будет перехватывать все сообщения? 

Какие сообщения? CGauge же графический компонент, а не оконный. Если только другого характера сообщения перехватывать, напр. нажатие кнопки, изменение заголовка окна и т.п.

PS Выложи скрин окна программы, которую ты перехватываешь.

Автор: fridkaratel 25.10.2007, 04:28
Вот... как происходит все:
1. Занести данные в файл, из которого ПСР автоматически подставляет данные в нужные поля
2. Нажать на кнопку Download
3. Получать значение TCGauge снизу

ВОт скрин...

Автор: fridkaratel 28.10.2007, 16:40
возник один вопрос...
пытаюсь создать динамически:
TToolButton *tb_my = NULL;

а потом найти компонент на форме и присвоить...
но компилятор ругается, мол expression syntax error... что делать?

Автор: 586 29.10.2007, 05:19
Цитата(fridkaratel @  28.10.2007,  17:40 Найти цитируемый пост)
но компилятор ругается, мол expression syntax error... что делать? 

без кода трудно что-либо сказать...
Код
#include <ComCtrls.hpp>
#include <ToolWin.hpp>

Автор: fridkaratel 29.10.2007, 08:59
ок, спасибо... у меня глюк был - было два файла Unit1.cpp и откуда-то взятый Unit1.h, который вообще не нужне в DLL smile

а как можно организовать обмен сообщениями между двумя программами? мне необходимо посылать команды другому приложению, но в DLL надо как-то объявить...

Интересует такой вот формат:
Программа1 -> SendMessage(<param>) -> Программа2
switch (<param>)
{ case <something>: ....}

Как лучше всего это сделать? То есть я бы хотел посылать какие-нибудь переменные из Программы1 в Программу2, в свою очередь Программа2 обработала операции, связанные с посланной переменной и отправила Программе1.

Получается логикак как у клиент-серверного приложения... 

Автор: pandrew 29.10.2007, 10:37
Цитата(fridkaratel @  29.10.2007,  08:59 Найти цитируемый пост)
а как можно организовать обмен сообщениями между двумя программами? мне необходимо посылать команды другому приложению...

Существует много способов организации связи между двумя приложениями. Поиск рулит. smile 
Вариант с SendMessage тоже возможен. Надо только помнить об асинхронности обмена.

Автор: fridkaratel 29.10.2007, 11:05
искал и читал - наткнулся на pipe... это капец - сложно слишком... smile поэтому ищу другие варианты.. или подробное разъяснение... ;)

Автор: pandrew 29.10.2007, 11:36
В BCB есть пример обмена через COM. 
тут еще:
http://forum.vingrad.ru/forum/topic-141384/unread-1/hl/%25D0%25BE%25D0%25B1%25D0%25BC%25D0%25B5%25D0%25BD/index.html
http://www.citforum.ru/programming/32less/les21.shtml

Для обмена через посылку сообщений, все что надо, как-то узнать кому посылать сообщения (например через FindWindow). 
Любая программа имеет право послать любому окну SendMessage(Handle,msg,wParam,lParam), msg >= WM_USER, wParam и lParam - твои параметры. В оконной процедуре принимающей стороны, надо их как-то обработать.

Добавлено через 3 минуты и 4 секунды
тут еще
http://www.sql.ru/forum/actualthread.aspx?bid=21&tid=414150&hl=%ee%e1%ec%e5%ed
Однако совсем просто не будет.

Автор: fridkaratel 29.10.2007, 16:30
вот, я хочу через SendMessage() посылать свои сообщения через wParam и lParam, только как их принимать не знаю...

PS: почитаю предложенное ;)

Автор: 586 29.10.2007, 16:59
Цитата(fridkaratel @  29.10.2007,  16:30 Найти цитируемый пост)
вот, я хочу через SendMessage() посылать свои сообщения через wParam и lParam, только как их принимать не знаю

из DLL в своё приложение? Поищи по форуму BEGIN_MESSAGE_MAP.

Автор: pandrew 29.10.2007, 17:21
Цитата(fridkaratel @  29.10.2007,  16:30 Найти цитируемый пост)
вот, я хочу через SendMessage() посылать свои сообщения через wParam и lParam, только как их принимать не знаю...

У каждого WinControl (и у TCustomForm) есть метод DefaultHandler(void *Message).
Его можно подменить в производном классе (твоя форма) приблизительно так:
Код

void __fastcall TMyForm::DefaultHandler(void* Message)
{  TMessage *msg=(TMessage*)Message;
    switch(msg->Msg)
    {  case WM_USER:  // твое сообщение   
          if(msg->WParam == ....)
          {   ....  // какая-то обработка
                msg->Result=tue;return;
          } 
    }
    TForm::::DefaultHandler(Message);  // вызов базового метода
}

Автор: fridkaratel 29.10.2007, 17:25
586, скачал исходники по одной из ссылок, которые предложил pandrew.


pandrew, ок, поробую твой код применить

Автор: fridkaratel 29.10.2007, 17:50
586, а как вставить то, что ты предложил? и куда?
как я понял, надо воткнуть вот это:
Код

    BEGIN_MESSAGE_MAP
      MESSAGE_HANDLER(WM_COPYDATA, TMessage, OnMyMessage)
    END_MESSAGE_MAP(TForm)
<...>
void __fastcall TForm1::OnMyMessage(TMessage& Message)
{
//  свои действия
//  ShowMessage("Yo");
  COPYDATASTRUCT *cpDS;
  cpDS = (COPYDATASTRUCT *)(void *)Message.LParam;
  MyData = (TMyData *)(cpDS->lpData);
  ShowMessage(MyData->Text1);
//  Edit1->Text = MyData->Text1;
//  Edit2->Text = IntToStr((int)MyData->Data1);
//  Edit3->Text = IntToStr((int)MyData->Data2);
};


Но не понимаю - у меня же не инициализируется в DLL класс формы, а предложенный MESSAGE инициализируется в разделе public формы... что делать? Создать новую форму? есть другие варианты?
**********************

pandrew, а как это встроить в DLL? ведь я не могу просто так взять и обхявить функцию void __fastcall TMyForm::DefaultHandler(void* Message)... у меня в DLL нет формы... как быть?

Автор: 586 29.10.2007, 18:36
В DLL создавай поток и делай в нём на WinApi окно и цикл обработки сообщений.

Автор: fridkaratel 30.10.2007, 05:18
а можно примерчик?

Автор: pandrew 30.10.2007, 10:53
Цитата(fridkaratel @  29.10.2007,  17:50 Найти цитируемый пост)
pandrew, а как это встроить в DLL? ведь я не могу просто так взять и обхявить функцию void __fastcall TMyForm::DefaultHandler(void* Message)... у меня в DLL нет формы... как быть? 

А при чем тут DLL? Ранее ты спрашивал:
Цитата(fridkaratel)
 я бы хотел посылать какие-нибудь переменные из Программы1 в Программу2, в свою очередь Программа2 обработала операции, связанные с посланной переменной и отправила Программе1. 

В DLL есть экспортируемые функции. Кто мешает их просто вызвать? smile 

Автор: fridkaratel 30.10.2007, 14:01
да, есть два приложения, и между ними надо посылать и принимать сообщения...

может я забыл упомянуть, но мне необходимо инициализировать функции посылки и приема сообщения в Программе 2 через DLL, т.е. в программе нет функций и объявлений - они должны быть в DLL...

К Программе 1 есть доступ, и можно с ней делать все, что угодно, т.е. Программа 1 - это моя программа, а Программа 2 - не моя...

вот...

как тут быть?

Автор: 586 30.10.2007, 16:13
Код
CloseHandle(CreateThread(0, 0, ThreadProc, 0, 0, NULL));

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  switch(uMsg)
  {
  case WM_CLOSE:
    DestroyWindow(hWnd);
    break;

  case WM_DESTROY:
    PostQuitMessage( 0 );
    break;

  /* ...  */
  }
  return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

DWORD CALLBACK ThreadProc(LPVOID)
{
  // HINSTANCE hinst=GetModuleHandle(0);
  WNDCLASSEX wc;
  memset(&wc, 0, sizeof(wc));
  wc.cbSize=sizeof(wc);
  wc.lpfnWndProc=WndProc;
  wc.hInstance=hinst;
  wc.lpszClassName=TEXT("ClientWndClass");   // имя класса
  RegisterClassEx(&wc);
  HWND hWnd=CreateWindowEx(0, wc.lpszClassName, 0/*заголовок окна*/, 0, 0, 0, 0, 0, NULL, NULL, wc.hInstance, 0);

  MSG msg;
  BOOL b;
  while((b=GetMessage(&msg, hWnd, 0, 0)) && (b!=-1))
       DispatchMessage(&msg);

  return 0;
}

Поток нужен для того, чтобы функция DllMain завершилась (вернула 1 или 0 - модуль корректно загружен или нет). Система может ожидать завершения этой ф-ции и процесс может зависнуть. Поэтому делаем отдельный поток.
Имя класса и заголовок окна задаёшь сам. В своём приложении ищешь с помощью ф-ции FindWindow.

Автор: fridkaratel 30.10.2007, 16:48
586, спасибо - буду пытаться ;)

PS: а ты когда в аське бываешь? никак застать не могу.... по ней можно к тебе обращаться за помощью в срочных делах?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)