Форум: "WinAPI";
Текущий архив: 2005.02.06;
Скачать: [xml.tar.bz2];
ВнизHook wanted Найти похожие ветки
← →
Mihey_temporary © (2004-12-13 23:08) [0]У кого-нибудь есть навскидку готовый пример глобального хука на мышь, отсылающего программе сообщения при передвижении мыши и нажатии на кнопки? Требуется и хук, и обработка сообщений в главной программе.
← →
Palladin © (2004-12-13 23:24) [1]http://www.delphimaster.ru/articles/hooks/index.html
← →
Mihey_temporary © (2004-12-13 23:55) [2]
> Palladin © (13.12.04 23:24) [1]
Статья, безусловно, по хукам, но нет конкретно про мышь. Мне больше интересует именно тело мышиной процедуры и обработка сообщений в главной программе.
← →
Palladin © (2004-12-14 00:00) [3]Это все безусловно подробно описано в справке WinAPI.
← →
Юрий Зотов © (2004-12-14 00:49) [4]> Mihey_temporary © (13.12.04 23:55) [2]
http://delphimaster.net/view/1-1102341741/
Вам нужно сделать то же самое, только посылать форме из хука нужно не свое сообщение, а WM_COPYDATA, передавая в нем в wParam - ноль (идентификатор того, что сообщение пришло именно от хука) а в lParam - адрес структуры COPYDATASTRUCT, которая в dwData будет содержать само сообщение мыши (оно приходит в хук, как wParam), в lpData будет содержать адрес структуры MOUSEHOOKSTRUCT (он приходит в хук, как lParam), а в cbData будет содержать размер структуры MOUSEHOOKSTRUCT.
Еще момент - вызывайте CallNextHookEx всегда, независимо от значения nCode.
← →
Mihey_temporary © (2004-12-14 01:19) [5]
> Palladin © (14.12.04 00:00) [3]
> Это все безусловно подробно описано в справке WinAPI.
Я ищу лёгкое решение.
← →
Юрий Зотов © (2004-12-14 01:21) [6]> Mihey_temporary © (14.12.04 01:19) [5]
Желаю удачи.
← →
Mihey_temporary © (2004-12-14 21:24) [7]
> Желаю удачи.
Вот так люди переходят на VCL. И всё-таки...
> Вам нужно сделать то же самое, только посылать форме из
> хука нужно не свое сообщение, а WM_COPYDATA, передавая в
> нем в wParam - ноль (идентификатор того, что сообщение пришло
> именно от хука) а в lParam - адрес структуры COPYDATASTRUCT,
> которая в dwData будет содержать само сообщение мыши (оно
> приходит в хук, как wParam), в lpData будет содержать адрес
> структуры MOUSEHOOKSTRUCT (он приходит в хук, как lParam),
> а в cbData будет содержать размер структуры MOUSEHOOKSTRUCT.
А зачем такая сложность с WM_COPYDATA? Почему нужно использовать это дело, а не как в том примере. Я хочу своё сообщение!
← →
Leonid Troyanovsky © (2004-12-14 21:32) [8]
> Mihey_temporary © (14.12.04 21:24) [7]
> А зачем такая сложность с WM_COPYDATA? Почему нужно использовать
> это дело, а не как в том примере. Я хочу своё сообщение!
Добавь в mmf MOUSEHOOKSTRUCT и пользуй.
Только копировать туда надо самому (move).
--
С уважением, LVT.
← →
Юрий Зотов © (2004-12-14 21:45) [9]> Mihey_temporary © (14.12.04 21:24) [7]
> А зачем такая сложность с WM_COPYDATA? Почему нужно
> использовать это дело, а не как в том примере.
Потому что хук глобальный. Это значит, что он должен передать данные из одного АП в другое. А длина этих данных такова, что в параметры сообщения их не запихнешь. Значит, если не рассматривать уж слишком вычурные способы, то либо [8], либо WM_COPYDATA, либо обрезать данные до 8 байт и передавать в параметрах.
← →
Mihey_temporary © (2004-12-14 22:56) [10]Что-то не пашет хук и ИМХО ошибка где-то в связке:
В приложении:
procedure TTestForm.CopyData(var Msg: TWMCopyData);
var Coord: TPoint;
begin
Coord := TMouseHookStruct(Msg.CopyDataStruct^.lpData^).pt;
Caption := IntToStr(Coord.x) + IntToStr(Coord.y);
inherited;
end;
В библиотеке:
var
MouseHooker: HHook;
BackHandle: HWND;
function MouseProc(Code: Integer; wParam: Word; lParam: Longint): Longint; stdcall;
var copyDataStruct: TCopyDataStruct;
lAddition: Integer;
begin
if Code in [HC_ACTION, HC_NOREMOVE] then
begin
CopyDataStruct.lpData := @lParam;
CopyDataStruct.cbData := SizeOf(TMouseHookStruct);
CopyDataStruct.dwData := wParam;
lAddition := Integer(@CopyDataStruct);
PostMessage(BackHandle, WM_COPYDATA, 0, lAddition);
end;
Result := CallNextHookEx(MouseHooker, Code, wParam, lParam);
end;
Вылетает с AV.
← →
Mihey_temporary © (2004-12-14 22:58) [11]Беспокоит меня вот это дело:
> CopyDataStruct.lpData := @lParam;
Получается, адрес указателя, что-ли.
← →
Leonid Troyanovsky © (2004-12-14 23:13) [12]
> Mihey_temporary © (14.12.04 22:58) [11]
> Беспокоит меня вот это дело:
> > CopyDataStruct.lpData := @lParam;
lpData
Points to data to be passed to the receiving application.
lParam и так содержит указатель на данные, т.е.
CopyDataStruct.lpData := Pointer(lParam);
В dwData обычно указывают окно (для идентификации),
в данном случае можно GetCurrentThreadId
И, потом, какой такой Post? Только SendMessage.
Если свое сообщение + mmf, тоже, кстати Send.
--
С уважением, LVT.
← →
Mihey_temporary © (2004-12-14 23:39) [13]Всё равно висит:
Приложение:
unit TestUnit;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
type
TTestForm = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
procedure CopyData(var Msg: TWMCopyData); message WM_COPYDATA;
public
{ Public declarations }
end;
type TSetMouseHook = procedure (WND: HWND); stdcall;
TRemoveMouseHook = procedure; stdcall;
var
TestForm: TTestForm;
hcDll: THandle;
SetMouseHook: TSetMouseHook;
RemoveMouseHook: TRemoveMouseHook;
implementation
{$R *.DFM}
procedure TTestForm.CopyData(var Msg: TWMCopyData);
var Coord: TPoint;
begin
Coord := TMouseHookStruct(Msg.CopyDataStruct^.lpData^).pt;
Caption := IntToStr(Coord.x) + IntToStr(Coord.y);
inherited;
end;
procedure TTestForm.FormCreate(Sender: TObject);
begin
hcDll := LoadLibrary("mousehook.dll");
If hcDll <= HINSTANCE_ERROR then
begin
MessageDlg("You are looser!", mtError, [mbOk], 0);
Application.Terminate;
end;
SetMouseHook := GetProcAddress(hcDll, "SetMouseHook");
If not Assigned(SetMouseHook) then
begin
MessageDlg("You are looser!", mtError, [mbOk], 0);
Application.Terminate;
end;
RemoveMouseHook := GetProcAddress(hcDll, "RemoveMouseHook");
If not Assigned(RemoveMouseHook) then
begin
MessageDlg("You are looser!", mtError, [mbOk], 0);
Application.Terminate;
end;
SetMouseHook(Handle);
end;
procedure TTestForm.FormDestroy(Sender: TObject);
begin
RemoveMouseHook;
FreeLibrary(hcDll);
end;
end.
Библиотека:
library MouseHook;
uses
SysUtils, Classes, Windows, Messages;
var
MouseHooker: HHook;
BackHandle: HWND;
function MouseProc(Code: Integer; wParam: Word; lParam: Longint): Longint; stdcall;
var copyDataStruct: TCopyDataStruct;
lAddition: Integer;
begin
if Code in [HC_ACTION, HC_NOREMOVE] then
begin
CopyDataStruct.lpData := Pointer(lParam);
CopyDataStruct.cbData := SizeOf(TMouseHookStruct);
// CopyDataStruct.dwData := wParam;
CopyDataStruct.dwData := GetCurrentThreadId;
lAddition := Integer(@CopyDataStruct);
SendMessage(BackHandle, WM_COPYDATA, 0, lAddition);
end;
Result := CallNextHookEx(MouseHooker, Code, wParam, lParam);
end;
procedure SetMouseHook(Wnd: HWND);
begin
BackHandle := Wnd;
MouseHooker := SetWindowsHookEx(WH_MOUSE, @MouseProc, HInstance, 0);
end;
procedure RemoveMouseHook;
begin
UnhookWindowsHookEx(MouseHooker);
end;
exports SetMouseHook,
RemoveMouseHook;
begin
end.
← →
Игорь Шевченко © (2004-12-15 00:23) [14]Mihey_temporary © (14.12.04 23:39) [13]
Ссылка на статью не зря ведь дадена была.
> var
> MouseHooker: HHook;
> BackHandle: HWND;
Отгадай, чему будут равны эти переменные при загрузке DLL в чужое пространство, если учесть, что сегмент данных у каждого экземпляра DLL свой.
> Я ищу лёгкое решение.
Легкое решение - читать статью и искать способ разделения этих двух переменных между всеми экземплярами DLL, например, используя Memory-Mapped Files.
С уважением,
← →
Mihey_temporary © (2004-12-15 01:09) [15]
> Легкое решение - читать статью и искать способ разделения
> этих двух переменных между всеми экземплярами DLL, например,
> используя Memory-Mapped Files.
Да не буду я читать эту статью. Вообще у вас тут всё оффтопик - мне нужен пример готовый работающий, а не учения про сообщения и проецируемые файлы. Вот дали ссылку:
http://delphimaster.net/view/1-1102341741/
Но чего-то не идёт. Возьмите, скопируйте код, если вам не сложно, добавьте пару волшебных штрихов и выдайте назад.
← →
Piter © (2004-12-15 01:52) [16]Ну что же МИХЕЙ-ИЩУЩИЙ-ЛЕГКИХ-ПУТЕЙ. Вот тебе код моей библиотеки:
library piter_hook;
uses
Windows;
const
cMMFileName = "piter-hook_{E891D15B-DD53-4BC8-81F4-E0BF8A5573B6}";
type
PGlobalData = ^TGlobalData;
TGlobalData = packed record
HookProcessId: DWORD;
HookHandle: HHOOK;
WindowHandle: THandle;
idMsg: LongWord;
end;
var
GlobalData: PGlobalData ;
MapHandle: THandle;
function DeleteHook(CheckProcess: boolean): boolean;
begin
Result := false;
if GlobalData <> nil then
with GlobalData^ do
if HookHandle<>0 then
if (not CheckProcess) or (GetCurrentProcessId = HookProcessId) then
begin
Result := UnHookWindowsHookEx(HookHandle) ;
if Result then
HookHandle := 0;
end;
end;
function RemoveShellHook: boolean; stdcall;
begin
Result := DeleteHook(True);
end;
function ShellProc(nCode: integer; wParam: LongWord;
lParam: LongWord): integer; stdcall;
begin
Result := 0;
if GlobalData <> nil then
with GlobalData^ do
begin
if IsWindow(WindowHandle) then
SendMessage(WindowHandle, idMsg, wParam, nCode)
else
DeleteHook(False);
CallNextHookEx(HookHandle, nCode, wParam, lParam);
end;
end;
function SetShellHook(CallbackWindow: THandle;
idCallBackMessage: LongWord): boolean; stdcall;
begin
Result := false;
if GlobalData <> nil then
with GlobalData^ do
if ( HookHandle = 0 ) and ( IsWindow(CallbackWindow) ) then
begin
HookHandle := SetWindowsHookEx(WH_SHELL, @ShellProc, HInstance, 0);
Result := HookHandle <> 0;
if Result then
begin
HookProcessId := GetCurrentProcessId ;
WindowHandle := CallbackWindow ;
idMsg := idCallBackMessage ;
end;
end;
end;
procedure OpenSharedData;
var
Size: integer;
begin
Size := SizeOf(TGlobalData);
MapHandle := CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE,
0, Size, cMMFileName);
if MapHandle = 0 then exit;
GlobalData := MapViewOfFile(MapHandle, FILE_MAP_ALL_ACCESS, 0, 0, Size);
end;
procedure CloseSharedData;
begin
UnmapViewOfFile(GlobalData);
CloseHandle(MapHandle);
end;
procedure DLLEntryProc(dwReason: DWord);
begin
case dwReason of
DLL_PROCESS_ATTACH: OpenSharedData;
DLL_PROCESS_DETACH:
begin
RemoveShellHook ;
CloseSharedData;
end;
end;
end;
exports
SetShellHook, RemoveShellHook;
begin
DLLProc := @DLLEntryProc;
DLLEntryProc(DLL_PROCESS_ATTACH);
end.
Правда, опять не все шоколадно. У меня хук WH_SHELL, а у тебя WH_MOUSE. Но если мы умеем хотя бы чуть чуть думать - то что-то может получится.
По крайней мере, продемонстрировано как работать с проецируемыми в память файлами.
А вообще интересная позиция - этого я читать не хочу, того тоже. А нафига ты вообще программированием занимаешься? Ты всегда планируешь чуть что - сюда со своими проблемами идти?
← →
Mihey_temporary © (2004-12-15 02:12) [17]
> Piter © (15.12.04 01:52) [16]
И код использования в программе, пожалуйста.
← →
Polevi © (2004-12-15 09:39) [18]и ключи от квартиры
← →
Polevi © (2004-12-15 09:40) [19]и вообще не понимаю людей которые чем-то помогают подобным личностям
← →
Mihey_temporary © (2004-12-15 14:21) [20]Всё нормально получилось, хук работает. Вот видите, статью не читал, а разобрался. Большое спасибо Piter"у за отличный пример. Юрий Зотов помог с WM_COPYDATA, а Leonid Troyanovsky с ошибками в коде - их тоже благодарю.
Осталась пара моментов.
У Piter"а в коде:
Result := false;
if GlobalData <> nil then
with GlobalData^ do
if ( HookHandle = 0 ) and ( IsWindow(CallbackWindow) ) then
begin
HookHandle := SetWindowsHookEx(WH_SHELL, @ShellProc, HInstance, 0);
Result := HookHandle <> 0;
if Result then
begin
HookProcessId := GetCurrentProcessId ;
WindowHandle := CallbackWindow ;
idMsg := idCallBackMessage ;
end;
end;
Так что же, если у нас будет глюк и GlobalData = nil, то цепочка хуков прервётся из-за нашей программы? Непорядок.
И вот ещё. Игорь Шевченко писал 15.12.04 в 00:23 в посте [14] следующее:
"> var
> MouseHooker: HHook;
> BackHandle: HWND;
Отгадай, чему будут равны эти переменные при загрузке DLL в чужое пространство, если учесть, что сегмент данных у каждого экземпляра DLL свой."
Непонятно конечно ничего, но я так понял, что непорядок почему-то с внутренней переменной MouseHooker и почему то неопрядок с хендлом как будто он зависит от АП. А у Piter"а в коде:
var
GlobalData: PGlobalData ;
MapHandle: THandle;
И с ними порядок. Что-то тут не стыкуется открыто.
← →
Digitman © (2004-12-15 14:35) [21]
> Непонятно конечно ничего
если "непонятно ничего" и впредь статьи ты читать/анализировать/вникать не намерен - подайся в управдомы .. ибо без теории ни-че-го путного из "программерских" потуг не выйдет.
← →
Юрий Зотов © (2004-12-15 15:33) [22]> Mihey_temporary © (15.12.04 14:21) [20]
> непорядок почему-то с внутренней переменной MouseHooker и
> почему то неопрядок с хендлом как будто он зависит от АП.
Именно. Зависит.
> а у Piter"а в коде:
> ...
> И с ними порядок. Что-то тут не стыкуется открыто.
Все прекрасно стыкуется. Piter использует ГЛОБАЛЬНЫЕ данные, а Вы - ЛОКАЛЬНЫЕ. Вот и вся разница, но на работу хука она оказывает РЕШАЮЩЕЕ влияние.
Вам действительно нужно прочесть статью и понять, ПОЧЕМУ и ЗАЧЕМ здесь нужен memory-mapped file.
← →
Mihey_temporary © (2004-12-15 15:42) [23]
> Именно. Зависит.
Как же он зависит, когда Handle - это уникальный идентификатор окна (в данном случае) в системе?
> Вам действительно нужно прочесть статью
Чтобы прочитать, мол, идите и читайте MSDN? Даром не надо.
← →
Piter © (2004-12-15 17:27) [24]Polevi © (15.12.04 9:40) [19]
да, это уже идет непрекрытое хамство. Самое интересное, что эти люди потом будут заводить тему, аналогичные этой - http://delphimaster.net/view/1-1102341741/ :(
← →
Piter © (2004-12-15 17:28) [25]Блин, вроде Mihey_temporary - ник мне известный, на форуме не впервой... ну зачем же так неуважать людей...
← →
Cobalt © (2004-12-15 17:35) [26]#ifdef Offtopic
Мне кажется, что это такой эксперимент.
##endif //Offtopic
← →
-=SS=- © (2004-12-15 17:52) [27]library M_Hook;
uses
Windows;
const
cMMFileName = "piter-hook_{E891D15B-DD53-4BC8-81F4-E0BF8A5573B6}";
type
PGlobalData = ^TGlobalData;
TGlobalData = packed record
HookProcessId: DWORD;
HookHandle: HHOOK;
WindowHandle: THandle;
idMsg: LongWord;
end;
var
GlobalData: PGlobalData ;
MapHandle: THandle;
function DeleteHook(CheckProcess: boolean): boolean;
begin
Result := false;
if GlobalData <> nil then
with GlobalData^ do
if HookHandle<>0 then
if (not CheckProcess) or (GetCurrentProcessId = HookProcessId) then
begin
Result := UnHookWindowsHookEx(HookHandle) ;
if Result then
HookHandle := 0;
end;
end;
function RemoveMouseHook: boolean; stdcall;
begin
Result := DeleteHook(True);
end;
function MouseProc(nCode: integer; wParam: LongWord;
lParam: LongWord): integer; stdcall;
begin
Result := 0;
if GlobalData <> nil then
with GlobalData^ do
begin
if IsWindow(WindowHandle) then
SendMessage(WindowHandle, idMsg, wParam, nCode)
else
DeleteHook(False);
CallNextHookEx(HookHandle, nCode, wParam, lParam);
end;
end;
function SetMouseHook(CallbackWindow: THandle;
idCallBackMessage: LongWord): boolean;
begin
Result := false;
if GlobalData <> nil then
with GlobalData^ do
if ( HookHandle = 0 ) then
begin
HookHandle := SetWindowsHookEx(WH_MOUSE, @MouseProc, HInstance, 0);
Result := HookHandle <> 0;
if Result then
begin
HookProcessId := GetCurrentProcessId ;
WindowHandle := CallbackWindow ;
idMsg := idCallBackMessage ;
end;
end;
end;
procedure OpenSharedData;
var
Size: integer;
begin
Size := SizeOf(TGlobalData);
MapHandle := CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE,
0, Size, cMMFileName);
if MapHandle = 0 then exit;
GlobalData := MapViewOfFile(MapHandle, FILE_MAP_ALL_ACCESS, 0, 0, Size);
end;
procedure CloseSharedData;
begin
UnmapViewOfFile(GlobalData);
CloseHandle(MapHandle);
end;
procedure DLLEntryProc(dwReason: DWord);
begin
case dwReason of
DLL_PROCESS_ATTACH: OpenSharedData;
DLL_PROCESS_DETACH:
begin
RemoveMouseHook ;
CloseSharedData;
end;
end;
end;
exports
SetMouseHook, RemoveMouseHook;
begin
DLLProc := @DLLEntryProc;
DLLEntryProc(DLL_PROCESS_ATTACH);
end.
в проге
function RemoveMouseHook: boolean; external "m_hook.dll";
function SetMouseHook(CallbackWindow: THandle;
idCallBackMessage: LongWord): boolean; external "m_hook.dll";
Это творение Pitera переделанное на Мышь.... у меня работает незнаю чем ты там сдрадаешь Михей но требовалось поменять несколько строк кода ...
← →
Юрий Зотов © (2004-12-15 18:24) [28]> Mihey_temporary © (15.12.04 15:42) [23]
> Как же он зависит, когда Handle - это уникальный идентификатор
> окна (в данном случае) в системе?
Этими словами Вы еще раз подтвердили, что "Вам действительно нужно прочесть статью и понять, ПОЧЕМУ и ЗАЧЕМ здесь нужен memory-mapped file".
Объяснять Вам всю кухню прямо здесь вряд ли кто станет. Потому что объяснения потянут еще на одну такую же статью - а зачем ее писать, если:
1. она и так уже написана;
2. читать Вы все равно не хотите.
← →
Mihey_temporary © (2004-12-15 19:42) [29]2 -=SS=-:
> Это творение Pitera переделанное на Мышь.... у меня работает
> незнаю чем ты там сдрадаешь Михей но требовалось поменять
> несколько строк кода ...
Так всё уже сделано. Кстати, интересно, как ты будешь принимать и обрабатывать сообщение в программе при своём решении?
2 Юрий Зотов:
> Этими словами Вы еще раз подтвердили, что "Вам действительно
> нужно прочесть статью и понять, ПОЧЕМУ и ЗАЧЕМ здесь нужен
> memory-mapped file".
Смотрите: ищу в статье информацию на тему WH_MOUSE. Автор пишет: "о которых каждый может прочитать в SDK, MSDN". Иду на MSDN. Там пишут, что обработка производится в специальной процедуре, например, с именем MouseProc и для подробностей смотрите её. Смотрим её и что мы видим:
LRESULT CALLBACK MouseProc( int nCode,
WPARAM wParam,
LPARAM lParam
);
Что это? Это что-то новое из языка Delphi? Ах нет, просто автор статьи по использованию хуков в Delphi ссылается на примеры, написанные на C++. Вот как это воспринимать?
В принципе, всё работает и не так уж много я узнал, чтобы так сказать, "добивать" досконально тему. Думаю, как нибудь в следующий раз почитаю, если актуальность такого подхода доживёт до этого раза.
← →
Leonid Troyanovsky © (2004-12-15 21:48) [30]
> Mihey_temporary © (15.12.04 14:21) [20]
> Непонятно конечно ничего, но я так понял, что непорядок
> почему-то с внутренней переменной MouseHooker и почему то
> неопрядок с хендлом как будто он зависит от АП. А у Piter"а
> в коде:
> var
> GlobalData: PGlobalData ;
> MapHandle: THandle;
> И с ними порядок. Что-то тут не стыкуется открыто.
A library can be used by several applications at once, but each application has a copy of the library in its own process space with its own set of global variables. For multiple libraries—or multiple instances of a library—to share memory, they must use memory-mapped files. Refer to the your system documentation for further information.
Т.е., глобальности GlobalData, MapHandle хватает лишь
на то, чтобы обобщить их между OpenSharedData и
хуковой процедурой (исполняемых в чужом процессе).
Зато, данные записанные в mmf, действительно глобальны,
и разделяются всеми процессами, открывшими оный mmf.
--
С уважением, LVT.
PS Кстати, "the your system documentation" - MSDN ;)
← →
Юрий Зотов © (2004-12-16 01:17) [31]> Mihey_temporary © (15.12.04 19:42) [29]
> автор статьи по использованию хуков в Delphi ссылается на
> примеры, написанные на C++. Вот как это воспринимать?
Так, что автор не считает нас, читателей, полнейшими чайниками. И он прав. Иначе бы ему пришлось писать не статью, а двадцатитомную книгу.
Есть такое понятие - ожидаемая аудитория. Учебник по матанализу пишется не для дошкольников, понимаете?
Вообще же, если программист Delphi не в состоянии понять код C (кстати, в данном случае даже без всяких плюсов), то ему стоит подумать о смене профессии. Потому что водителей "Жигулей" не бывает. Бывают просто водители.
> и не так уж много я узнал, чтобы так сказать, "добивать"
> досконально тему.
Дело Ваше. Но знайте: если Вы досконально не разобрались, что такое глобальные данные, зачем они здесь нужны и как реализуются - то тогда в этой теме Вы не поняли... ни-че-го.
Даже без всяких сомнений.
А решать - Вам.
P.S.
Плз, исправьте страничку, на которую Вы ссылаетесь в "Потрепаться". Я хотел ее посмотреть, но через несколько секунд просмотра рисунок свернулся в тонкую полоску вдоль левого края экрана. Соответственно, высота букв стала примерно 0.2 мм и читать их стало довольно трудно.
P.P.S.
ИМХО, уровень наших разговоров потихоньку растет. Как Вы считаете?
← →
Mihey_temporary © (2004-12-16 17:41) [32]
> P.S.
> Плз, исправьте страничку, на которую Вы ссылаетесь в "Потрепаться".
> Я хотел ее посмотреть, но через несколько секунд просмотра
> рисунок свернулся в тонкую полоску вдоль левого края экрана.
> Соответственно, высота букв стала примерно 0.2 мм и читать
> их стало довольно трудно.
Если вы используете IE, то дождитесь загрузки картинки, а затем наведите курсор на нижнюю часть картинки (сантиметр от нижнего края примерно). Прямо на ней появится кнопка, нажава на которую вы расширите картинку до первоначальных размеров. Также вы можете снять галочку с Enable Automatic Image Resizing в Tools -> Internet Options -> Advanced -> раздел Multimedia в списке. В Mozilla нужно просто щёлкнуть по картинке.
← →
Piter © (2004-12-16 20:16) [33]Юрий Зотов © (16.12.04 1:17) [31]
вы прирожденный учитель... это сколько же у вас терпения...
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2005.02.06;
Скачать: [xml.tar.bz2];
Память: 0.6 MB
Время: 0.04 c