Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 09.11.2009, 18:38   #11
Alex Cones
Trust no one.
Старожил
 
Аватар для Alex Cones
 
Регистрация: 07.04.2009
Сообщений: 6,526
По умолчанию

Если заюзать API, то можно почти полностью преобразить форму на экране. Советую поучить API функции.
+ Быстродействие
+ Микроскопический размер ехе
SQUARY PROJECT - НАБОР БЕСПЛАТНЫХ ПРОГРАММ ДЛЯ РАБОЧЕГО СТОЛА.
МОЙ БЛОГ
GRAY FUR FRAMEWORK - УДОБНАЯ И БЫСТРАЯ РАЗРАБОТКА WINAPI ПРИЛОЖЕНИЙ
Alex Cones вне форума Ответить с цитированием
Старый 11.11.2009, 13:51   #12
TwiX
Участник клуба
 
Аватар для TwiX
 
Регистрация: 28.07.2009
Сообщений: 1,510
По умолчанию

Как пользоваться SetParent?
Пробовал так:
Код:
procedure TForm1.Button1Click(Sender: TObject);      
var
  b:tbutton;
  h:hwnd;
begin
  h:=FindWindow('opWindow', nil);
  if h=0 then
  begin
    beep;
    exit;
  end;

  b:=TButton.Create(Self);
  b.Left:=10;
  b.Top:=5;
  b.Width:=100;
  b.Height:=90;
  b.Caption:='Test';
  b.Parent:=TWinControl(h);
end;
Ругается на TWinControl (это и понятно =) )
TwiX вне форума Ответить с цитированием
Старый 11.11.2009, 14:28   #13
JTG
я получил эту роль
Старожил
 
Аватар для JTG
 
Регистрация: 25.05.2007
Сообщений: 3,694
По умолчанию

windows.SetParent(Button1.Handle, h);
Но так делать нельзя, access violation гарантирован. Чтоб прилепить VCL-кнопку в чужое окно есть метод TButton.CreateParented, он используется в ActiveX-компонентах, там куча своих нюансов.
пыщь
JTG вне форума Ответить с цитированием
Старый 11.11.2009, 14:36   #14
TwiX
Участник клуба
 
Аватар для TwiX
 
Регистрация: 28.07.2009
Сообщений: 1,510
По умолчанию

Жаль...
А что надо писать b:=TButton.create(тут?)
Я всегда писал self, но не понимал зачем, ведь в конструкторе кнопки вызывается конструкторе кнопки вызывается конструктор self'а, а свойство Parent всё-равно приходится вписывать \=
TwiX вне форума Ответить с цитированием
Старый 11.11.2009, 14:49   #15
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
но не понимал зачем
Чтобы компонент знал кто его родитель.
Цитата:
ведь в конструкторе кнопки вызывается конструкторе кнопки вызывается конструктор self'а
Кнопочного self'a а тт что ты в create(тут?) пихаешь совсем другой - это "указатель" на компонент, описываемый в этом юните, классу которого принадлежит процедура где ты TButton.create(тут?) вызываешь.
Цитата:
а свойство Parent всё-равно приходится вписывать \=
Ну они для разных немного нужд. Я тоже не понимаю зачем так сделано. но так сделано.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 11.11.2009, 16:41   #16
JTG
я получил эту роль
Старожил
 
Аватар для JTG
 
Регистрация: 25.05.2007
Сообщений: 3,694
По умолчанию

Традиционно издеваемся над калькулятором

Dll
Код:
library injector;

uses
  Windows,
  Messages,
  SysUtils,
  Classes;

const
  btnID = 65432;
  WM_START = WM_USER+100;

var
  wnd:hwnd;
  rect: TRect;
  w,h: Integer;
  OldWndProc: integer;
  ok: boolean=false;

function NewWndProc(wnd: HWND; Msg: Cardinal; wParam: wParam; lParam: lParam): Longint; stdcall;
begin
  Result := CallWindowProc(Pointer(OldWndProc), wnd, Msg, wParam, lParam);
  case Msg of
    WM_START: begin
                GetWindowRect(wnd, rect);
                w := rect.Right - rect.Left;
                h := rect.Bottom - rect.Top;
                CreateWindowEx(0,'Button','Тыць!',WS_VISIBLE or WS_CHILD,w,5,75,30,wnd,btnID,hInstance,nil);
                SetWindowPos(wnd,0,0,0,w+100,h,SWP_NOZORDER+SWP_NOMOVE);
                UpdateWindow(wnd);
              end;
    WM_COMMAND: if wParam = btnId then MessageBox(wnd, 'It''s alive! ALIVE!!!','',0);
  end;
end;

procedure DllMain(reason: integer);
begin
   case reason of
   DLL_PROCESS_ATTACH: ;
   DLL_PROCESS_DETACH: if ok then SetWindowLong(wnd, GWL_WNDPROC, Integer(@OldWndProc));
   end;
end;

begin
  DllProc := @DllMain;
  DllProc(DLL_PROCESS_ATTACH);

  wnd := FindWindow('SciCalc', 'Калькулятор');
  if Win32Check(longbool(wnd)) then
  begin
    OldWndProc := GetWindowLong(wnd, GWL_WNDPROC);
    SetWindowLong(wnd, GWL_WNDPROC, Integer(@NewWndProc));
    PostMessage(wnd, WM_START, 0, 0);
    ok := true;
  end;
end.
Loader
Код:
program Loader;

{$APPTYPE CONSOLE}

uses windows, sysutils;

type shell = packed record
               PushCommand:byte;
               PushArgument:DWORD;
               CallCommand:WORD;
               CallAddr:DWORD;
               PushExitThread:byte;
               ExitThreadArg:dword;
               CallExitThread:word;
               CallExitThreadAddr:DWord;
               AddrLoadLibrary:pointer;
               AddrExitThread:pointer;
               LibraryName:array[0..MAX_PATH] of char;
             end;

Function InjectDll(Process: dword; ModulePath: PChar): boolean;
var
  Memory:pointer;
  Code: dword;
  BytesWritten: dword;
  ThreadId: dword;
  hThread: dword;
  hKernel32: dword;
  Inject: shell;
begin
  Result := false;
  Memory := VirtualAllocEx(Process, nil, sizeof(Inject), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  if Memory = nil then Exit;
  Code := dword(Memory);
  With Inject do
  begin
    PushCommand    := $68;
    PushArgument   := code + $1E;
    CallCommand    := $15FF;
    CallAddr       := code + $16;
    PushExitThread := $68;
    ExitThreadArg  := 0;
    CallExitThread := $15FF;
    CallExitThreadAddr := code + $1A;
    hKernel32 := GetModuleHandle('kernel32.dll');
    AddrLoadLibrary := GetProcAddress(hKernel32, 'LoadLibraryA');
    AddrExitThread  := GetProcAddress(hKernel32, 'ExitThread');
    lstrcpy(@LibraryName, ModulePath);
  end;
  WriteProcessMemory(Process, Memory, @inject, sizeof(inject), BytesWritten);
  hThread := CreateRemoteThread(Process, nil, 0, Memory, nil, 0, ThreadId);
  if hThread = 0 then Exit;
  CloseHandle(hThread);
  Result := True;
end;

var
  PID, hProcess: DWORD;
  DLL: PChar;
begin
  DLL := PChar(ExtractFilePath(paramstr(0))+'injector.dll');
  GetWindowThreadProcessId(FindWindow('SciCalc', 'Калькулятор'), @Pid);
  hprocess := OpenProcess($1F0FFF, False, Pid);
  InjectDll(hProcess, DLL);
  CloseHandle(hprocess);
end.
пыщь

Последний раз редактировалось JTG; 11.11.2009 в 16:44.
JTG вне форума Ответить с цитированием
Старый 11.11.2009, 23:26   #17
TwiX
Участник клуба
 
Аватар для TwiX
 
Регистрация: 28.07.2009
Сообщений: 1,510
По умолчанию

Цитата:
Сообщение от Stilet Посмотреть сообщение
Кнопочного self'a а тт что ты в create(тут?) пихаешь совсем другой - это "указатель" на компонент, описываемый в этом юните, классу которого принадлежит процедура где ты TButton.create(тут?) вызываешь.
Тут я не совсем понял =) Можно ещё раз и помедленней?)

За калькулятор тож спасибо) Правда я ни разу ещё не работал с длл - завтра буду разбираться)
TwiX вне форума Ответить с цитированием
Старый 12.11.2009, 07:52   #18
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
Можно ещё раз и помедленней?)
"Пмдленнней пжасста... я зпсвью..."
Смотри, вот ты пишешь

b:=TButton.create(Self)

Этот код помешен в неком... ну допустим событии скажем при создании формы:
Код:
procedure TForm1.FormCreate(Sender: TObject);
begin
 b:=TButton.Create(self);
end;
Это эквивалентно:
Код:
procedure TForm1.FormCreate(Sender: TObject);
begin
 b:=TButton.Create(Form1);
end;
Так вот Self в данном случае вернет тебе тот объект, событие которого сейчас описывается, т.е. в данном случае это объект класса TForm1.

Стало быть self - это указатель на некий экземпляр формы, ну логично предположить что на Form1 (если брать стандартные случаи, бывает что ты создаешь форму или в принципе объект динамически - F:=Tform1.Create. Тогда Self в том событии укажет на F)

А смысл указывать TButton.Create(self); вот в чем: Если посмотришь в генофонд можно найти такой вот код:
Код:
constructor TComponent.Create(AOwner: TComponent);
begin
  FComponentStyle := [csInheritable];
  if AOwner <> nil then AOwner.InsertComponent(Self);
end;
Который говорит нам что передавая
TButton.create(Self) ты указываешь куда этот вновь созданный TButton помещать - AOwner.InsertComponent всего лишь помещает эту кнопку в контейнер родителя, но он совсем не обязан указывать этой кнопке кто будет ее родителем

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

Понял смысл?
I'm learning to live...

Последний раз редактировалось Stilet; 12.11.2009 в 07:54.
Stilet вне форума Ответить с цитированием
Старый 12.11.2009, 16:28   #19
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

извините что вмешиваюсь...

в Делфи сделали как то хитро(через Ж)
Owner это компонент который при своем уничтожении уничтожает и всех у кого он числется как Владелец...
а Parent это компонент ответственный за отображение(в основном) компонента...
то есть если Родителя не стало, то дитя живет...
но на практике как то редко возникает последняя ситуация.

если например создаем диалог только внутри одной процедуры то ставить ей владельца не нужно(сами уничтожим потом)
владельца стоит ставить для избежания потерь памяти.

прошу прощение за не в темность
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 12.11.2009, 16:43   #20
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
в Делфи сделали как то хитро(через Ж)
Видимо Борландовцы для чего-то другого такую стратегию задумали.
Я тоже от нее не в восторге.
Может быть смысл был в том что не всякий компонент, который помещается в контейнер может иметь свойство Parent - это уже на TWinControl такое пошло, но ведь он основан на TComponent. Значит Дядьки из Борланда просто прдостереглись от несчасных случаев если компонент или контрол вдруг не будетиметь свойство Parent. Но как показала практика это чрезвычайная редкость.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Добавить/удалить строку нажатием на кнопку из сохранением формул gleod Microsoft Office Excel 28 23.07.2009 11:20
Клик по чужому LISTVIEW Neoteric Общие вопросы Delphi 6 14.04.2009 12:16
Как в 2007 из ВБА добавить кнопку на панель быстрого доступа IgorGO Microsoft Office Excel 2 30.09.2008 13:52
Можно ли собственными силами установить на сайт форму добавить объявление? oio1 Помощь студентам 1 23.04.2008 08:02
Как на кнопку добавить картинку? xTANATOSx Общие вопросы Delphi 3 05.11.2007 13:11