Форум: "Потрепаться";
Текущий архив: 2004.12.05;
Скачать: [xml.tar.bz2];
ВнизСоставление нового FAQ для этого сайта Найти похожие ветки
← →
Piter © (2004-11-01 22:53) [0]Неоднократно поднимались темы, вот подниму еще раз.
В прошлый раз застопорились, теперь я постараюсь собирать FAQ.
Но писать самому - не хватит никаких сил. Поэтому очень хочется рассчитывать на помощь.
В частности, очень требуются грамотные ответы с примерами кода и с комментариями на вопросы FAQ. При этом желательно умещаться с рамки FAQ, то есть не статью писать, а достаточно кратко. Но понятно :)
Хотя можно и статью - тогда это пойдет в раздет "Статьи" :)
В частности, сейчас нужны ответы на вопросы:
Как запустить процесс от имени другого пользователя
Как создать таймер средствами Win32Api
Как эмулировать нажатие клавиши или кнопки мыши.
Как прочитать заголовок или Edit из чужого окна
Как передать строку (длинные данные) из одной программы в другую
При этом если кто соберется написать - подумайте, ведь это надо донести считай до начинающих людей, поэтому примеры должны быть как можно изящнее, демонстрирующие нужную функциональность, но без лишнего кода. И не надо забывать о словах, ибо сухой код полезен - но можно чуть чуть и пояснить.
Ну а в случае ошибки - мастера, думаю, всегда исправят!
Заранее спасибо!
← →
Piter © (2004-11-01 22:54) [1]Как мне кажется пример грамотного ответа:
Вопрос: как запустить другую программу и дождаться ее окончания.
Ответ: для запуска внешнего процесса будем использовать богатую на возможности функцию CreateProcess.
При успешном создании нового процесса эта функция заполняет передаваемую структуру PROCESS_INFORMATION, в частности поле hProcess, которое является указателем на новый процесс.
В случае надобности мы передаем полученный указатель на новый процесс в функцию WaitForSingleObject вместе со значением infinite.
В результате, WaitForSingleObject прервет выполнение потока нашей программы до тех пор, пока нужный нам процесс не завершится. В случае со значением infinite функция будет ждать бесконечно долго, поэтому вы должны быть уверены, что нужный процесс когда-нибудь завершится, иначе ваш поток никогда не получит управление обратно (в случае, если данный код исполняется для основного потока как в примере - это приведет к зависанию программы).
Пример:
unit ufCreateProcess;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
//Функция для создания нового процесса
//Параметры:
// aCommand: Строка для выполнения исполняемого файла(полный путь)
// aShow: Показывать/не показывать окно нового процесса
// aWaitExit: Ожидать/не ожидать завершения процесса
function ExecCmd(const aCommand: String;const aShow, aWaitExit: Boolean): Boolean;
var
pi:PROCESS_INFORMATION;
si:STARTUPINFO;
cmdLine,Path: String;
begin
Result := False;
ZeroMemory(@si,sizeof(si));
si.cb:=SizeOf(si);
si.dwFlags := STARTF_FORCEONFEEDBACK+STARTF_USESHOWWINDOW;
if aShow then si.wShowWindow := SW_SHOWNORMAL else si.wShowWindow := SW_HIDE;
Path := ExtractFilePath(aCommand);
cmdLine := aCommand;
Result :=
CreateProcess( nil, // No module name (use command line).
PChar(cmdLine), // Command line.
nil, // Process handle not inheritable.
nil, // Thread handle not inheritable.
False, // Set handle inheritance to FALSE.
0, // No creation flags.
nil, // Use parent"s environment block.
PChar(Path), // Use parent"s starting directory.
si, // Pointer to STARTUPINFO structure.
pi ); // Pointer to PROCESS_INFORMATION structure.
if Result then
begin
CloseHandle(pi.hThread);
if aWaitExit then WaitForSingleObject( pi.hProcess, infinite );
CloseHandle(pi.hProcess);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ExecCmd(ExtractFilePath(ParamStr(0))+"pkzip test.zip",True,False);
end;
end.
← →
Rouse_ © (2004-11-01 22:58) [2]Миш, ИМХО нужно Сашу Панова трясти, потомучто специально для того еще разо много наработок было, но вот что-то результаты :(
← →
panov © (2004-11-01 22:58) [3]>Piter
Почту получил?
← →
panov © (2004-11-01 22:59) [4]>Rouse_ © (01.11.04 22:58) [2]
Если Михаил завтра напомнит, перешлю твои наработки - нашел...
← →
Rouse_ © (2004-11-01 23:00) [5]> [4] panov © (01.11.04 22:59)
Тогда завтра еще вышлю, у меня их много. Чай почти месяц над ними сидел :)
← →
Verg © (2004-11-01 23:01) [6]
> При этом если кто соберется написать - подумайте, ведь это
> надо донести считай до начинающих людей, поэтому примеры
> должны быть как можно изящнее, демонстрирующие нужную функциональность,
> но без лишнего кода.
Тема уже философская. "Должны быть", "надо", "изящнее".....
Если уж ты хотел бы подянть такую загадочную тему, то уж объясни мне, плиzzz (как принято спрашивать) почему, зачем и для чего?
Только....
> примеры
> должны быть как можно изящнее, демонстрирующие нужную функциональность,
> но без лишнего кода
Так и вот, простой вопрос - мотивация...
← →
panov © (2004-11-01 23:02) [7]>Rouse_ © (01.11.04 23:00) [5]
А у меня, увы, так и не доходят руки. Сегодня Михаилу целый день выбирал время, чтобы некоторые материалы скомпоновать и отослать.
← →
Rouse_ © (2004-11-01 23:03) [8]> Так и вот, простой вопрос - мотивация...
Ну тут все очень просто...
Ты же не спрашиваешь у врача, почему он тебя лечит, так и тут... Все сугубо добровольно...
Зы: Кстати твои наработки (которые ты мне присылал) тоже в FAQ ;)
И за них отдельное спасибо...
← →
VID © (2004-11-01 23:05) [9]Verg © (01.11.04 23:01) [6]
Если бы все рассуждали так как ты, то в мире не было бы халявы. Но она есть, значит не все такие как ты.
← →
Verg © (2004-11-01 23:26) [10]
> Если бы все рассуждали так как ты, то в мире не было бы
> халявы.
Если бы все рассуждали как я, то в мире бы вообще никого не было, кроме меня. И даже халявы :))))))
> Но она есть, значит не все такие как ты.
Вот так... Через "халяву" человек приходит к мудрости. Становятся очевидными такие сложные выкладки ума...
← →
Piter © (2004-11-01 23:44) [11]Verg © (01.11.04 23:01) [6]
Если уж ты хотел бы подянть такую загадочную тему, то уж объясни мне, плиzzz (как принято спрашивать) почему, зачем и для чего?
то есть, ты меня отговариваешь составлять FAQ, так?
А вообще, рекомендую тебе написать на adm@delphimaster.ru и спросить у Максима какого собственно хрена он горбатился над этим сайтом ночами, причем абсолютно бесплатно?
А в ответ получал зачастую - "почему не работает, почему сайт такой лажовый?"
← →
Piter © (2004-11-01 23:45) [12]Verg © (01.11.04 23:26) [10]
да и вообще. Если бы кто говорил - не удивился, но ты? ЗАЧЕМ ты отвечаешь на вопросы?
← →
Rouse_ © (2004-11-01 23:50) [13]> [12] Piter © (01.11.04 23:45)
Так, стоп, Миш ты не прав...
Если у Verg-а и бывают признаки хандры, то это не значит что нужно на него наезжать...
И тем более я лично могу принести ему респект за его ответы в конференции сети и вообще всем можно задать вопрос "а какого вы вообще сидите на форуме и еще отвечатете"... ;)
← →
Verg © (2004-11-01 23:52) [14]
> А вообще, рекомендую тебе написать на adm@delphimaster.ru
> и спросить у Максима какого собственно хрена он горбатился
> над этим сайтом ночами, причем абсолютно бесплатно?
Хм... Я как-то не привык для своих вопросов пользоваться посредниками. Да и для ответов, между прочим, тоже. И тебе не советую привыкать...
> то есть, ты меня отговариваешь составлять FAQ, так?
Ох, уж эти капризы...
← →
Mihey_temporary © (2004-11-01 23:53) [15]
> Как создать таймер средствами Win32Api
> Как эмулировать нажатие клавиши или кнопки мыши.
ИМХО на эти вопросы есть исчерпывающие ответы в других источниках или нужно обязательно с нуля своё?
← →
jack128 © (2004-11-01 23:54) [16]Piter © (01.11.04 22:53)
Как эмулировать нажатие клавиши или кнопки мыши.
Для мыши.
procedure MouseClick(Pt: TPoint; BackCursor: boolean = True);
// Переводим экранные координаты к принятым в mouse_event
function ScreenToAbsolute(const Pt: TPoint): TPoint;
begin
Result.x := Round(Pt.x * 65535 / Screen.Width);
Result.y := Round(Pt.y * 65535 / Screen.Height);
end;
var
OldPt: TPoint;
begin
if BackCursor then
OldPt := ScreenToAbsolute(Mouse.CursorPos);
Pt := ScreenToAbsolute(Pt);
{Переместим курсор мыши}
Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_MOVE, Pt.x, Pt.y, 0, 0);
{Нажамаем левую кнопку мыши}
Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_LEFTDOWN, Pt.x, Pt.y, 0, 0);
{Отпускаем левую кнопки мыши}
Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_LEFTUP, Pt.x, Pt.y, 0, 0);
if BackCursor then
{Перемещаем кнопку мыши обратно}
Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_MOVE, OldPt.x, OldPt.y, 0, 0);
end;
Например поместим на форму две кнопки Button1 и Button2 и в их обработчиках напишем следующееprocedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage("Test");
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
MouseClick(Button1.ClientToScreen(Point(2, 2)), True); // Кликаем по первой кнопке..
end;
← →
Rouse_ © (2004-11-01 23:57) [17]> ИМХО на эти вопросы есть исчерпывающие ответы в других источниках
> или нужно обязательно с нуля своё?
К примеру огромное кол-во вопросов пережевываемых в конференции Сети давно должны быть удостоены FAQ...
← →
Verg © (2004-11-02 00:09) [18]
> ЗАЧЕМ ты отвечаешь на вопросы?
Ты и в самом деле думаешь, что я задал риторический вопрос?
← →
Gero © (2004-11-02 00:22) [19]
> Как передать строку (длинные данные) из одной программы
> в другую
Чтобы передать другому приложению строку(или другие длинные данные) нужно послать ему сообщение WM_COPYDATA с соответствующими параметрами.
Например:
procedure SendStringToWindow(S: string; Wnd: HWND);
var
SendData: TCopyDataStruct;
begin
if Wnd > 0 then
begin
with Send do
begin
dwData := 0;
cbData := Length(S) + 1;
lpData := PChar(S);
end;
SendMessage(Wnd, WM_COPYDATA, 0, Longint(@Send));
end;
end
Если нам понадобится отправить какую-либо строку другому нашему приложению, мы пишем:
var
Wnd: HWND;
...
Wnd := FindWindow("TForm2", "Form2");
if Wnd > 0 then
SendStringToWindow("Hello!", Wnd);
Вот пример обработки такого сообщения в другой программе:
TForm2 = class(TForm)
private
procedure WMCopyData(var Msg: TWMCopyData); message WM_COPYDATA;
...
end;
...
procedure TDMCMainForm.WMCopyData(var Msg: TWMCopyData);
var
Text: string;
begin
if Msg.CopyDataStruct <> nil then
begin
Text := string(Msg.CopyDataStruct^.lpData);
ShowMessage("Получен текст: " + Text);
end;
end;
← →
Gero © (2004-11-02 00:29) [20]
> unit ufCreateProcess;
>
> interface
>
> uses
> Windows, Messages, SysUtils, Variants, Classes, Graphics,
> Controls, Forms,
> Dialogs, StdCtrls;
>
> type
> TForm1 = class(TForm)
> Button1: TButton;
> procedure Button1Click(Sender: TObject);
> private
> { Private declarations }
> public
> { Public declarations }
> end;
>
> var
> Form1: TForm1;
>
> implementation
>
> {$R *.dfm}
А этот мусор еще зачем?
← →
Verg © (2004-11-02 00:31) [21]
> Gero © (02.11.04 00:22)
> var
> SendData: TCopyDataStruct;
> begin
> if Wnd > 0 then
> begin
> with Send do
А Send - это что?
← →
Gero © (2004-11-02 00:33) [22]
> Verg © (02.11.04 00:31)
Да, описка, там и еще далее в одном месте не Send, а SendData.
← →
GuAV © (2004-11-02 00:46) [23]Piter © (01.11.04 22:53)
Как запустить процесс от имени другого пользователя
http://delphimaster.net/view/4-1099137400/
Игорь Шевченко там ответил.
Кстати тему поднятую там тоже можно добавит в FAQ
← →
GuAV © (2004-11-02 00:47) [24]Piter © (01.11.04 22:53)
Как создать таймер средствами Win32Api
Добавлю к этому вопросу:
Если я не привязываю таймер к окну а используюprocedure TimerProc(hWnd: HWND; uMsg: Cardinal;
idEvent: PCardinal; dwTime: DWORD); stdcall;
должен ли быть код в TimerProc потокобезопасным ?
← →
panov © (2004-11-02 09:55) [25]>Gero © (02.11.04 0:33) [22]
Да, описка, там и еще далее в одном месте не Send, а SendData.
Все ответы должны быть проверены на синтаксис и исполнимость.
← →
Gero © (2004-11-02 18:03) [26]
> panov © (02.11.04 09:55)
Да, сорри, писал прямо тут, а код взял из проекта, над которым сейчас работаю.
← →
Gero © (2004-11-02 18:14) [27]Как передать строку (длинные данные) из одной программы в другую
Чтобы передать другому приложению строку(или другие длинные данные) нужно послать ему сообщение WM_COPYDATA с соответствующими параметрами.
Например:procedure SendStringToWindow(S: string; Wnd: HWND);
var
SendData: TCopyDataStruct;
begin
if Wnd > 0 then
begin
with SendData do
begin
dwData := 0;
cbData := Length(S) + 1;
lpData := PChar(S);
end;
SendMessage(Wnd, WM_COPYDATA, 0, Longint(@SendData));
end;
end;
Если нам понадобится отправить какую-либо строку другому нашему приложению, мы пишем:var
Wnd: HWND;
...
Wnd := FindWindow("TForm2", "Form2");
if Wnd > 0 then
SendStringToWindow("Hello!", Wnd);
Вот пример обработки такого сообщения в другой программе:TForm2 = class(TForm)
private
procedure WMCopyData(var Msg: TWMCopyData); message WM_COPYDATA;
...
end;
...
procedure TForm2.WMCopyData(var Msg: TWMCopyData);
var
Text: string;
begin
if Msg.CopyDataStruct <> nil then
begin
Text := string(Msg.CopyDataStruct^.lpData);
ShowMessage("Получен текст: " + Text);
end;
end;
← →
Игорь Шевченко © (2004-11-02 18:34) [28]
> Как запустить процесс от имени другого пользователя
unit main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TfMain = class(TForm)
Button: TButton;
procedure ButtonClick(Sender: TObject);
end;
var
fMain: TfMain;
implementation
uses
HSAdvApi;
{$R *.dfm}
procedure TfMain.ButtonClick(Sender: TObject);
begin
MyCreateProcess();
end;
procedure TfMain.MyCreateProcess;
const
UserName : WideString = "TESTUSER";
Password : WideString = "testuser";
ConstCommandLine : String = "CMD.EXE";
Title : WideString = "Test process";
Domain : WideString = "WORKGROUP";
var
MyStartupInfo : STARTUPINFO;
ProcessInfo : PROCESS_INFORMATION;
CommandLine : array[0..512] of WideChar;
begin
FillChar(MyStartupInfo, SizeOf(MyStartupInfo), 0);
MyStartupInfo.cb := SizeOf(MyStartupInfo);
StringToWideChar(ConstCommandLine, CommandLine,
Sizeof(CommandLine) div SizeOf(WideChar));
MyStartupInfo.lpTitle := PWideChar(Title);
if not CreateProcessWithLogonW (PWideChar(UserName), PWideChar(Domain),
PWideChar(Password), LOGON_WITH_PROFILE, nil,
CommandLine, 0, nil, nil, @MyStartupInfo, @ProcessInfo) then
RaiseLastWin32Error()
else begin
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
end;
end;
end.unit HSAdvApi;
interface
uses
Windows;
function CreateProcessWithLogonW (const lpUsername : PWideChar;
const lpDomain : PWideChar; const lpPassword : PWideChar;
dwLogonFlags : DWORD; const lpApplicationName : PWideChar;
lpCommandLine : PWideChar; dwCreationFlags : DWORD;
lpEnvironment : Pointer; const lpCurrentDirectory : PWideChar;
lpStartupInfo : PStartupInfo;
lpProcessInfo : PProcessInformation) : Boolean; stdcall;
const
LOGON_WITH_PROFILE = $00000001;
LOGON_NETCREDENTIALS_ONLY = $00000002;
LOGON_ZERO_PASSWORD_BUFFER = $80000000;
implementation
uses
SysUtils;
{ ADVAPI32.DLL functions }
type
TCreateProcessWithLogonW =
function (const lpUsername : PWideChar;
const lpDomain : PWideChar; const lpPassword : PWideChar;
dwLogonFlags : DWORD; const lpApplicationName : PWideChar;
lpCommandLine : PWideChar; dwCreationFlags : DWORD;
lpEnvironment : Pointer; const lpCurrentDirectory : PWideChar;
lpStartupInfo : PStartupInfo;
lpProcessInfo : PProcessInformation) : Boolean; stdcall;
const
DllName = "advapi32.dll";
var
DllHandle : THandle;
_CreateProcessWithLogonW : TCreateProcessWithLogonW;
function InitLib : Boolean;
begin
if DllHandle = 0 then
if Win32Platform = VER_PLATFORM_WIN32_NT then begin
DllHandle := LoadLibrary(DllName);
if DllHandle <> 0 then begin
@_CreateProcessWithLogonW := GetProcAddress(DllHandle,
"CreateProcessWithLogonW");
end;
end;
Result := (DllHandle <> 0);
end;
function NotImplementedBool : Boolean;
begin
SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
Result := false;
end;
function CreateProcessWithLogonW (const lpUsername : PWideChar;
const lpDomain : PWideChar; const lpPassword : PWideChar;
dwLogonFlags : DWORD; const lpApplicationName : PWideChar;
lpCommandLine : PWideChar; dwCreationFlags : DWORD;
lpEnvironment : Pointer; const lpCurrentDirectory : PWideChar;
lpStartupInfo : PStartupInfo;
lpProcessInfo : PProcessInformation) : Boolean; stdcall;
begin
if InitLib and Assigned(_CreateProcessWithLogonW) then
Result := _CreateProcessWithLogonW(lpUsername, lpDomain, lpPassword,
dwLogonFlags, lpApplicationName, lpCommandLine, dwCreationFlags,
lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInfo)
else
Result := NotImplementedBool;
end;
initialization
finalization
if DllHandle <> 0 then
FreeLibrary(DllHandle);
end.
← →
Piter © (2004-11-02 21:22) [29]ну ответы-то перед включением в FAQ я все равно буду проверять по любому, если есть возможность. Такие описки я исправлю :)
Cпасибо тем, кто ответил!
← →
Piter © (2004-11-05 18:21) [30]Народ! А как насчет эмуляции нажатии клавиши?
← →
Поручик © (2004-11-05 18:29) [31]Piter © (05.11.04 18:21) [30]
Пихни в faq модуль SendKeys, могу выслать.
← →
Piter © (2004-11-05 21:45) [32]Форум сегодня сверхдинамичный - ветка уже уплыла :)
← →
Piter © (2004-11-05 21:45) [33]Поручик © (05.11.04 18:29) [31]
целый модуль пихать не буду. Нужен короткий пример
← →
Piter © (2004-11-06 13:02) [34]Люди! Активнее...
← →
Piter © (2004-11-06 15:48) [35]Требуются ответы на следующие вопросы:
Как перенести/установить/настроить алиасы BDE на другой компьютер
Как нормализовать вид ScrollBar (90% ответ - Fetchall :))
Вопрос про точное хранение денежных сумм и т.п.
Как в выпадающий список DBComboBox вывести все значения поля из таблицы?
Как вставить TCheckBox в поле DBGrid ?
Как раскрасить отдельные строки в TDBGgrid
А также вот, я даже не знаю о чем это:
Где взять proxies.pas
Плюс еще от Розыча, Digitman"а, Verg"а или других обитателей сетей надеюсь получить грамотные ответы на вопрос (ну народ, очент желательно с пояснениями, подводными камнями, которые могут встретиться и прочее):
Определение IP по DNS-имени хоста и наоборот
Как узнать локальный МАС (IP) локального и удаленного компьютера
Как отправить файл по сети на другой компьютер
Как разговаривать посети
Как отправить письмо с вложением
Как установить - разорвать соединение DialUp
Как запретить доступ к моему компу, но чтоб остались общие ресурсы
Как получить доступ к общим ресурсам удаленного компьютера, зная пароль
Как самому написать Sniffer
Как самому написать Proxy
Как самому написать FireWall
Как получить в локальной сети список:
- имен пользователей
- ресурсов
- доменов
- рабочих групп,
Как работать с низкоуровневыми сокетами WinSock
← →
YurikGL © (2004-11-06 15:57) [36]
> Как вставить TCheckBox в поле DBGrid ?
Использовать TDBGridEH из EHLib...
← →
VMcL © (2004-11-06 16:06) [37]>>Piter © (06.11.04 15:48) [35]
>Как самому написать FireWall
Да что уж мелочиться? "Как самому написать операционную систему?" :-)
>Как самому написать Sniffer
Как самому написать Proxy
Как самому написать FireWall
Кстати, слово "самому" явно лишнее. Раз человек использовал код из FAQ, то какое тут "самому"? Он же не сел, сам прочитал документацию, разобрался и написал?
>Как работать с низкоуровневыми сокетами WinSock
Хм. Первый раз слышу, чтобы гнезда WinSock по уровням делились. Может имеется в виду "Как работать с сокетами WinSock на чистом WinAPI?"
?
← →
KSergey © (2004-11-06 16:38) [38]> Вопрос про точное хранение денежных сумм и т.п.
А Currency - это не точно?
> Как в выпадающий список DBComboBox вывести все значения
> поля из таблицы?
А в чем тут подвох? Вроде оно и так всегда все выводит... Если специально не предпринимать доп. усилий... Да и это по хорошему любая книга. (кроме "Граф Монте-Кристо")
> Как вставить TCheckBox в поле DBGrid ?
> Как раскрасить отдельные строки в TDBGgrid
Может здесь правильнее будет дать ссылку на соответствующие статьи с "Королевства"? По-молему, их прочтение принесет много больше пользы, нежели просто "Вставить в OnDrawCell...". Да и по объему они не велики.
← →
Gero © (2004-11-06 16:39) [39]
> Где взять proxies.pas
Это было в предыдущей ветке, которую я тебе на мыло на мыло отсылал.
← →
KSergey © (2004-11-06 16:40) [40]Не знаю на сколько такой вопрос F, но есть решение подсветки строки TMemo... Если причесать... (всей, не отдельных элементов!)
Страницы: 1 2 3 4 вся ветка
Форум: "Потрепаться";
Текущий архив: 2004.12.05;
Скачать: [xml.tar.bz2];
Память: 0.6 MB
Время: 0.042 c