|
Примеры
работы с Windows API
1.Перехват нажатия на системные кнопки формы (закрытие
, минимизация окна и т.д.)
Сообщение WM_SYSCOMMAND приходит перед выполнением соответствующей
команды, что дает возможность переопределить код.
Описание :
WM_SYSCOMMAND
uCmdType = wParam; // type of system command requested
xPos = LOWORD(lParam); // horizontal postion, in screen coordinates
yPos = HIWORD(lParam); // vertical postion, in screen coordinates
Например, перехват события минимизации окна приложения:
Type TMain = class(TForm)
....
protected
Procedure WMGetSysCommand(var Message : TMessage) ; message WM_SYSCOMMAND;
end;
.....
//------------------------------------------------------------------------------
//Обработка сообщения WM_SYSCOMMAND (перехват минимизации окна)
//------------------------------------------------------------------------------
Procedure TMain.WMGetSysCommand(var Message : TMessage) ;
Begin
IF (Message.wParam = SC_MINIMIZE)Then Main.Visible:=False
Else Inherited;
End;Вернуться к содержанию
2.Ограничение на размеры формы
Используется обработка Windows сообщения WM_GETMINMAXINFO
Например, ограничение на уменьшение размера формы и на увеличение ее
по высоте:
//------------------------------------------------------------------------------
//ограничение на изменение размера формы
//------------------------------------------------------------------------------
procedure TFormBarParity.WMGetMinMaxInfo(var Message : TMessage);
type
PTMinMaxInfo = ^TMinMaxInfo;
begin
with PTMinMaxInfo(Message.LParam)^.ptMinTrackSize
do begin
x := 400;
y := 45;
end;
with PTMinMaxInfo(Message.LParam)^.ptMaxTrackSize
do begin
y := 45;
end;
inherited;
end;
//------------------------------------------------------------------------------
Вернуться к содержанию
3.Компонент TStringGrid - назначение
цвета для каждой строки, вывод содержимого ячейки в несколько строк
С помощью функции DrawText (Windows API), на событие TStringGrid.onDrawCell.
Причем, для того , чтобы длинная строка выводилась в ячейке в несколько
строк, необходимо явно добавить в нужные места символ перевода строки(CHR(13))
Примечание: В данном примере COLUMN_INVCOMING,
COLUMN_MESSAGE и ROW_HEADER мои собственные константы, с помощью которых
я определяю что и каким цветом в TStringGrid надо рисовать. То есть цвет
меняется во всех строках кроме ROW_HEADER в ячейке с номером COLUMN_MESSAGE.
И цвет определяется значением ячейки с номером COLUMN_INCOMING.
//------------------------------------------------------------------------------
procedure TFormHistory.ListHistoryDrawCell(Sender: TObject; Col,
Row: Integer; Rect: TRect; State: TGridDrawState);
Var
S : String;
DrawRect : TRect;
CurrentColor : TColor;
begin
// Определяем цвет строки в зависимости типа Imcoming
IF (Sender As TStrinGgrid).Cells[COLUMN_INCOMING , Row ] = '1'
Then CurrentColor:=clBlue
Else CurrentColor:=clMaroon;
IF (Sender As TStrinGgrid).Row = Row
Then CurrentColor := clHighlightText ;(Sender As TStrinGgrid).Canvas.font.color :=CurrentColor;S:=(Sender As TStrinGgrid).Cells[ Col, Row ];IF (Col= COLUMN_MESSAGE ) AND (Row <> ROW_HEADER) ThenBegin If Length(S) > 0 ThenBeginDrawRect: = Rect;
DrawText((Sender As TStrinGgrid).Canvas.Handle, Pchar(S), Length(S), DrawRect, dt_calcrect or dt_wordbreak or dt_left );If (DrawRect.bottom - DrawRect.top) > (Sender As TStrinGgrid).RowHeights[Row]Then (Sender As TStrinGgrid).RowHeights[row] : = (DrawRect.bottom- DrawRect.top)Else Begin DrawRect.Right:= Rect.Right;
(Sender As TStrinGgrid).Canvas.FillRect( DrawRect );DrawText((Sender As TStrinGgrid).Canvas.Handle, Pchar(S),
Length(S), DrawRect, dt_wordbreak or dt_left); End;
End;
End
Else IF Row <> ROW_HEADER
Then (Sender As TStrinGgrid).Canvas.Textout(rect.left+3, rect.top+3 , S );
end;
//------------------------------------------------------------------------------
Вернуться к содержанию
5. Убрать из формы Caption.
SetWindowLong (Main.Handle,GWL_STYLE,
GetWindowLong(Main.Handle, GWL_STYLE) AND NOT WS_CAPTION OR WS_SIZEBOX);
Вернуться к содержанию
6. Событие при потере и установке
фокуса для формы.
Примечание: В данном примере при потере
фокуса формой, PanelCaption окрашивается в цвет неактивного заголовка,
в случае получения фокуса формой - в цвет активного заголовка. То есть
цвет панели повторяет изменение цвета Caption самой формы.
Type TMain = class(TForm)
....
protected Procedure LastFocus(var Mess : TMessage) ; message WM_ACTIVATE;
End;
//--------------------------------------------------------------
Procedure TMain.LastFocus(var Mess : TMessage) ;
Begin
IF Mess.wParam = WA_INACTIVE
Then PanelCaption.Color:=clInactiveCaption
Else PanelCaption.Color:=clActiveCaption;
Inherited;
End;
Вернуться к содержанию
7.Добавить свой пункт в системное
меню приложения.
Добавить пункт в системное меню, написать обработчик его выбора и перехватить
сообщение о выборе пункта из системного меню.
Примечание: Константа WM_USER используется
в приложении для определения собственных сообщений.
Значения от 0 до (WM_USER-1) зарезервированы
для системных сообщений.
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure OnMyMenu;private
procedure WMSysCommand(var Msg: TWMSysCommand); message WM_SYSCOMMAND;
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
const
SC_MyMenuItem = WM_USER + 1;
//----------------------------------------------------
procedure TForm1.FormCreate(Sender: TObject);
begin
// добавление своего пункта в системное меню приложения
AppendMenu(GetSystemMenu(Handle, FALSE), MF_SEPARATOR, 0, '');
AppendMenu(GetSystemMenu(Handle, FALSE), MF_STRING,
SC_MyMenuItem, 'Новый пункт в меню');
end;
//----------------------------------------------------
procedure TForm1.OnMyMenu;
Begin
// Обработка нажатия на новый пункт меню
End;
//----------------------------------------------------
procedure TForm1.WMSysCommand(var Msg: TWMSysCommand);
begin
// перехват события выбора нового пункта меню
if Msg.CmdType = SC_MyMenuItem then
OnMyMenu else
inherited;
end;
//----------------------------------------------------
Вернуться к содержанию
Вопрос:
Как создать мигающий заголовок окна (пиктограмму)?
Ответ:
Можно воспользоваться функцией API FlashWindow():
Пример:
var Flash : bool;procedure TForm1.Timer1Timer(Sender: TObject); begin FlashWindow(Form1.Handle, Flash); FlashWindow(Application.Handle, Flash); Flash := not Flash; end;procedure TForm1.FormCreate(Sender: TObject); beginFlash := False; end;
Наверх к содержанию
Вопрос:
Иногда всплывающее меню моего приложения system tray не исчезает когда
оно теряет фокус. Как закрыть его?
Ответ:
При показе всплывающего меню установите foreground window, затем пошлите
сообщение WM_NULL после показа меню.
procedure TForm1.WndProc(var Msg : TMessage); var p : TPoint; begin case Msg.Msg of WM_USER + 1: case Msg.lParam of WM_RBUTTONDOWN: beginSetForegroundWindow(Handle);GetCursorPos(p);PopupMenu1.Popup(p.x, p.y);PostMessage(Handle, WM_NULL, 0, 0); end; end; end; inherited; end;
Наверх к содержанию
Вопрос:
Как узнать текущие время и дату по Гринвичу
Ответ:
Используя API фукцию GetSystemTime.
Пример:
procedure TForm1.Button1Click(Sender: TObject); var lt : TSYSTEMTIME; st : TSYSTEMTIME; begin GetLocalTime(lt); GetSystemTime(st); Memo1.Lines.Add('LocalTime = ' + IntToStr(lt.wmonth) + '/' + IntToStr(lt.wDay) + '/' + IntToStr(lt.wYear) + ' ' + IntToStr(lt.wHour) + ':' + IntToStr(lt.wMinute) + ':' + IntToStr(lt.wSecond)); Memo1.Lines.Add('UTCTime = ' + IntToStr(st.wmonth) + '/' + IntToStr(st.wDay) + '/' + IntToStr(st.wYear) + ' ' + IntToStr(st.wHour) + ':' + IntToStr(st.wMinute) + ':' + IntToStr(st.wSecond)); end;
Наверх к содержанию
Вопрос:
Как использовать процедуру mouse_event() для имитации событий мыши?
Ответ:
Приведенный пример демонстрирует использование API функции mouse_event()
для имитации событий мыши. При нажатии кнопки Button2 программа перемещает
курсор мыши на кнопку Button1 и щелкает по ней. Положение курсора мыши
задается в "абсолютных" координатах ("Mickeys"), где 65535 "Mickeys" равно
ширине экрана.
procedure TForm1.Button1Click(Sender: TObject); begin ShowMessage('Button 1 clicked'); end;procedure TForm1.Button2Click(Sender: TObject); var Pt : TPoint; begin{Позволим кнопке Button2 перерисоваться} Application.ProcessMessages;{Найдем координаты центра button 1} Pt.x := Button1.Left + (Button1.Width div 2); Pt.y := Button1.Top + (Button1.Height div 2);{Преобразуем Pt к координатам экрана} Pt := ClientToScreen(Pt);{Преобразуем Pt к "mickeys" (аболютным координатам курсора мышки} Pt.x := Round(Pt.x * (65535 / Screen.Width)); Pt.y := Round(Pt.y * (65535 / Screen.Height));{Переместим курсор мыши} 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);; end;
Наверх к содержанию
Вопрос:
Как программно закрыть другое приложение?
Ответ:
Отправьте этому приложению сообщение WM_QUIT
Пример:
PostMessage(FindWindow(Nil, 'Заголовок окна'), WM_QUIT, 0, 0);Где "Заголовок окна" - заголовок окна, которому Вы посылаете сообщение.
Наверх к содержанию
Вопрос:
Как спрятать и отключить кнопку "Пуск"?
Ответ:
Приведенный пример прячет и показывает кнопку "Пуск", а также разрешает
и запрещает ее.
Пример:
procedure TForm1.Button1Click(Sender: TObject); var Rgn : hRgn; begin{Cпрятать кнопку "Пуск"} Rgn := CreateRectRgn(0, 0, 0, 0); SetWindowRgn(FindWindowEx(FindWindow('Shell_TrayWnd', nil),0, 'Button',nil),Rgn,true); end;procedure TForm1.Button2Click(Sender: TObject); begin{Показать кнопку "Пуск"} SetWindowRgn(FindWindowEx(FindWindow('Shell_TrayWnd', nil),0, 'Button',nil),0,true); end;procedure TForm1.Button3Click(Sender: TObject); begin{Запретить кнопку "Пуск"} EnableWindow(FindWindowEx(FindWindow('Shell_TrayWnd', nil),0,'Button',nil),false); end;procedure TForm1.Button4Click(Sender: TObject); begin{Разрешить кнопку "Пуск"} EnableWindow(FindWindowEx(FindWindow('Shell_TrayWnd', nil),0,'Button',nil),true); end
Наверх к содержанию
Вопрос:
Как показать иконку, ассоциированной с данным типом файла?
Ответ:
ShellApi функция ExtractAssociatedIcon()
Пример:
uses ShellApi;procedure TForm1.Button1Click(Sender: TObject); var Icon : hIcon; IconIndex : word;begin IconIndex := 1; Icon := ExtractAssociatedIcon(HInstance,Application.ExeName,IconIndex);DrawIcon(Canvas.Handle, 10, 10, Icon); end;
Наверх к содержанию
Вопрос:
Как узнать путь к каталогам Windows?
Ответ:
Следующий пример получает полный список каталогов по умолчанию (Favorites,
Desktop, Programs, Fonts, SendTo, Start, Menu, Templates, Startup, Recent
and NetHood) Windows и заносит его в Memo.
Пример:
uses Registry;procedure TForm1.Button1Click(Sender: TObject); var reg : TRegistry; ts : TStrings; i : integer; begin reg := TRegistry.Create; reg.RootKey := HKEY_CURRENT_USER; reg.LazyWrite := false; reg.OpenKey('Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders', false); ts := TStringList.Create; reg.GetValueNames(ts); for i := 0 to ts.Count -1 do begin Memo1.Lines.Add(ts.Strings[i] + ' = ' + reg.ReadString(ts.Strings[i])); end; ts.Free; reg.CloseKey; reg.free; end;
Наверх к содержанию
Вопрос:
Как узнать полный путь и имя файла загруженной DLL?
Ответ:
См. пример
Пример:
uses Windows;procedure ShowDllPath stdcall; var TheFileName : array[0..MAX_PATH] of char; begin FillChar(TheFileName, sizeof(TheFileName), #0); GetModuleFileName(hInstance, TheFileName, sizeof(TheFileName)); MessageBox(0, TheFileName, 'The DLL file name is:', mb_ok); end;
Наверх к содержанию
Вопрос:
Как вызвать диалог 'Найти файлы и паки' проводника?
Ответ:
Приведенный пример показывает использование DDE для вызова диалога
'Найти файлы и паки' Explorerа. Диалог открывается на каталоге "C:\Download".
procedure TForm1.Button1Click(Sender: TObject); begin with TDDEClientConv.Create(Self) do begin ConnectMode := ddeManual; ServiceApplication := 'explorer.exe'; SetLink( 'Folders', 'AppProperties'); OpenLink; ExecuteMacro('[FindFolder(, C:\DOWNLOAD)]', False); CloseLink; Free; end; end;
Наверх к содержанию
Вопрос:
Существует ли способ для определение числа заданий spoolerа печати?
Ответ:
Spoolerа печати Windows посылает WM_SPOOLERSTATUS каждый раз при добавлении
и удалении заданий в очереди печати. В следующем примере показано как перехватить
это сообщение
Пример:
type TForm1 = class(TForm) Label1: TLabel; private { Private declarations } procedure WM_SpoolerStatus(var Msg : TWMSPOOLERSTATUS); message WM_SPOOLERSTATUS; public { Public declarations } end;var Form1: TForm1;implementation{$R *.DFM}procedure TForm1.WM_SpoolerStatus(var Msg : TWMSPOOLERSTATUS); begin Lable1.Caption := IntToStr(msg.JobsLeft) + ' Jobs currenly in spooler'; msg.Result := 0; end;
Наверх к содержанию
Вопрос:
Извлечение пиктограммы из exe, dll или ico-файла
Ответ:
Функция SHELLAPI ExtractIconEx:
Обратите внимание - в примере функции обьявленны иначе, чем в модуле
ShellAPI
type ThIconArray = array[0..0] of hIcon; type PhIconArray = ^ThIconArray;function ExtractIconExA(lpszFile: PAnsiChar; nIconIndex: Integer; phiconLarge : PhIconArray; phiconSmall: PhIconArray; nIcons: UINT): UINT; stdcall; external 'shell32.dll' name 'ExtractIconExA';function ExtractIconExW(lpszFile: PWideChar; nIconIndex: Integer; phiconLarge: PhIconArray; phiconSmall: PhIconArray; nIcons: UINT): UINT; stdcall; external 'shell32.dll' name 'ExtractIconExW';function ExtractIconEx(lpszFile: PAnsiChar;nIconIndex: Integer;phiconLarge : PhIconArray;phiconSmall: PhIconArray;nIcons: UINT): UINT; stdcall; external 'shell32.dll' name 'ExtractIconExA';procedure TForm1.Button1Click(Sender: TObject); var NumIcons : integer; pTheLargeIcons : phIconArray; pTheSmallIcons : phIconArray; LargeIconWidth : integer; SmallIconWidth : integer; SmallIconHeight : integer; i : integer; TheIcon : TIcon; TheBitmap : TBitmap; begin NumIcons := ExtractIconEx('C:\Program Files\Borland\Delphi 3\BIN\delphi32.exe', -1, nil, nil, 0); if NumIcons > 0 then begin LargeIconWidth := GetSystemMetrics(SM_CXICON); SmallIconWidth := GetSystemMetrics(SM_CXSMICON); SmallIconHeight := GetSystemMetrics(SM_CYSMICON); GetMem(pTheLargeIcons, NumIcons * sizeof(hIcon)); GetMem(pTheSmallIcons, NumIcons * sizeof(hIcon)); FillChar(pTheLargeIcons^, NumIcons * sizeof(hIcon), #0); FillChar(pTheSmallIcons^, NumIcons * sizeof(hIcon), #0);ExtractIconEx('C:\Program Files\Borland\Delphi 3\BIN\delphi32.exe', 0, pTheLargeIcons, pTheSmallIcons, numIcons);{$IFOPT R+}{$DEFINE CKRANGE}{$R-}{$ENDIF} for i := 0 to (NumIcons - 1) do begin DrawIcon(Form1.Canvas.Handle,i * LargeIconWidth,0,pTheLargeIcons^[i]); TheIcon := TIcon. Create; TheBitmap := TBitmap.Create; TheIcon.Handle := pTheSmallIcons^[i]; TheBitmap.Width := TheIcon.Width; TheBitmap.Height := TheIcon.Height; TheBitmap.Canvas.Draw(0, 0, TheIcon); TheIcon.Free; Form1.Canvas.StretchDraw(Rect(i * SmallIconWidth, 100, (i + 1) * SmallIconWidth, 100 + SmallIconHeight),TheBitmap); TheBitmap.Free; end;{$IFDEF CKRANGE}{$UNDEF CKRANGE}{$R+}{$ENDIF} FreeMem(pTheLargeIcons, NumIcons * sizeof(hIcon)); FreeMem(pTheSmallIcons, NumIcons * sizeof(hIcon)); end; end;end.
Наверх к содержанию
Вопрос:
Как запускать мою программу на каждом старте Windows?
Ответ:
Пример работает и для Win32и для Win16.
uses Registry, {For Win32} IniFiles; {For Win16}{$IFNDEF WIN32} const MAX_PATH = 144; {$ENDIF}{For Win32} procedure TForm1.Button1Click(Sender: TObject); var reg: TRegistry; begin reg := TRegistry.Create; reg.RootKey := HKEY_LOCAL_MACHINE; reg.LazyWrite := false; reg.OpenKey('Software\Microsoft\Windows\CurrentVersion\Run', false); reg.WriteString('My App', Application.ExeName); reg.CloseKey; reg.free; end;{For Win16} procedure TForm1.Button2Click(Sender: TObject); var WinIni : TIniFile; WinIniFileName : array[0..MAX_PATH] of char; s : string; begin GetWindowsDirectory(WinIniFileName, sizeof(WinIniFileName)); StrCat(WinIniFileName, '\win.ini'); WinIni := TIniFile.Create(WinIniFileName); s := WinIni.ReadString('windows','run',''); if s = '' then s := Application.ExeName else s := s + ';' + Application.ExeName; WinIni.WriteString('windows','run',s); WinIni.Free; end;
Наверх к содержанию
Вопрос:
Я хочу определить момент окончания изменения размера или перемещения
окна. Перехватываю сообщения WM_SIZE и WM_MOVE но я получаю много таких
сообщений а мне нужно узнать когда именно пользователь закончил перенос
или изменение размеров окна. Возможно ли это?
Ответ:
В следующем примере показан перехват сообщения WM_EXITSIZEMOVE Хотя
сообщение документированно только для Windows NT оно работает точно так
же и под Windows 95. Обратите внимание что Вы можите перехватить сообщение
WM_ENTERSIZEMOVEдля определения момента начала пользователем операции изменения
размера или перемещения окна.
Пример:
type TForm1 = class(TForm) private { Private declarations } public procedure WMEXITSIZEMOVE(var Message: TMessage);message WM_EXITSIZEMOVE; { Public declarations } end;var Form1: TForm1;implementation{$R *.DFM} procedure TForm1.WMEXITSIZEMOVE(var Message: TMessage); begin Form1.Caption := 'Finished Moving and sizing'; end;
Наверх к содержанию
Вопрос:
Как определить время последнего доступа к файлу?
Ответ:
См пример. Примечание: не все файловые системы поддерживают время последнего
доступа к файлу.
Пример:
procedure TForm1.Button1Click(Sender: TObject); var SearchRec : TSearchRec; Success : integer; DT : TFileTime; ST : TSystemTime; begin Success := SysUtils.FindFirst('C:\autoexec.bat', faAnyFile, SearchRec);if (Success = 0) and (( SearchRec.FindData.ftLastAccessTime.dwLowDateTime <> 0) or ( SearchRec.FindData.ftLastAccessTime.dwHighDateTime <> 0))then begin FileTimeToLocalFileTime(SearchRec.FindData.ftLastAccessTime,DT); FileTimeToSystemTime(DT,ST); Memo1.Lines.Clear; Memo1.Lines.Add('AutoExec.Bat was last accessed at:'); Memo1.Lines.Add('Year := ' + IntToStr(st.wYear)); Memo1.Lines.Add('Month := ' + IntToStr(st.wMonth)); Memo1.Lines.Add('DayOfWeek := ' + IntToStr(st.wDayOfWeek)); Memo1.Lines.Add('Day := ' + IntToStr(st.wDay)); Memo1.Lines.Add('Hour := ' + IntToStr(st.wHour)); Memo1.Lines.Add('Minute := ' + IntToStr(st.wMinute)); Memo1.Lines.Add('Second := ' + IntToStr(st.wSecond)); Memo1.Lines.Add('Milliseconds := ' + IntToStr(st.wMilliseconds)); end; SysUtils.FindClose(SearchRec); end;
Наверх к содержанию
Вопрос:
Как использовать функцию Shell API SHBrowseForFolder чтобы позволить
пользователю выбрать каталог?
Ответ:
См. пример
Пример:
uses ShellAPI, ShlObj;procedure TForm1.Button1Click(Sender: TObject); var TitleName : string; lpItemID : PItemIDList; BrowseInfo : TBrowseInfo; DisplayName : array[0..MAX_PATH] of char; TempPath : array[0..MAX_PATH] of char; begin FillChar(BrowseInfo, sizeof(TBrowseInfo), #0); BrowseInfo.hwndOwner := Form1.Handle; BrowseInfo.pszDisplayName := @DisplayName; TitleName := 'Please specify a directory'; BrowseInfo.lpszTitle := PChar(TitleName); BrowseInfo.ulFlags := BIF_RETURNONLYFSDIRS; lpItemID := SHBrowseForFolder(BrowseInfo); if lpItemId <> nil then begin SHGetPathFromIDList(lpItemID, TempPath); ShowMessage(TempPath); GlobalFreePtr(lpItemID); end; end;
Наверх к содержанию
Вопрос:
Как получить дескриптора окна Window, сожержащего DOS программу или
программу консольного режима?
Ответ:
В следуещем примере используется функция Windows API FindWindow().
Обратите внимание, что WndClass консольного окна отличаются для Windows
95 и Window NT и заголовок окна может содержать полный путь под Windows
NT.
Пример:
procedure TForm1.Button1Click(Sender: TObject); var info : TOSVersionInfo; ClassName : string; Title : string; begin{Проверяем - Win95 или NT.} info.dwOSVersionInfoSize := sizeof(info); GetVersionEx(info); if (info.dwPlatformId = VER_PLATFORM_WIN32_NT) then begin ClassName := 'ConsoleWindowClass'; Title := 'Command Prompt'; end else begin ClassName := 'tty'; Title := 'MS-DOS Prompt'; end; ShowMessage(IntToStr(FindWindow(PChar(ClassName), PChar(Title)))); end;
Наверх к содержанию
Вопрос:
Возможно ли определить факта изменения системного времени другим приложением?
Ответ:
Следующий прмер перехватывает событие WM_TIMECHANGE. примечание: Приложение
, изменяющее системное время должно посылать сообщение WM_TIMECHANGE всем
окнам.
type TForm1 = class(TForm) private { Private declarations } procedure WMTIMECHANGE(var Message: TWMTIMECHANGE);message WM_TIMECHANGE; public { Public declarations } end;var Form1: TForm1;implementation{$R *.DFM}procedure TForm1.WMTIMECHANGE(var Message: TWMTIMECHANGE); begin Form1.Caption := 'Time Changed'; end;
Наверх к содержанию
Вопрос:
Как очистить пункт документы меню кнопки Пуск
Ответ:
Вызовите Windows API функцию SHAddToRecentDocs() передав nil вместо
имени файла в качестве параметра.
Пример:
uses ShlOBJ;procedure TForm1.Button1Click(Sender: TObject); begin SHAddToRecentDocs(SHARD_PATH, nil); end;
Наверх к содержанию
Вопрос:
Как добавить пункт к системному меню приложения?
Пример:
type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); private { Private declarations } procedure WMSysCommand(var Msg: TWMSysCommand); message WM_SYSCOMMAND; public { Public declarations } end;var Form1: TForm1;implementation{$R *.DFM}const SC_MyMenuItem = WM_USER + 1;procedure TForm1.FormCreate(Sender: TObject); begin AppendMenu(GetSystemMenu(Handle, FALSE), MF_SEPARATOR, 0, ''); AppendMenu(GetSystemMenu(Handle, FALSE),MF_STRING,SC_MyMenuItem,'My Menu Item'); end;procedure TForm1.WMSysCommand(var Msg: TWMSysCommand); begin if Msg.CmdType = SC_MyMenuItem then ShowMessage('Got the message') else inherited; end;
Наверх к содержанию
Вопрос:
Как создание нестандартную процедуру разбиения слов при переносах для
TEdit, TMemo или TRichEdit?
Ответ:
В следующем примере создается процедура разбиения слов при переносах
для TMemo. Заметьте, что реализованная процедура просто всегда разрешает
перенос. Для дополнительной информации см.таже документацию к сообщению
EM_SETWORDBREAKPROC.
var OriginalWordBreakProc : pointer; NewWordBreakProc : pointer;function MyWordBreakProc(LPTSTR : pchar;ichCurrent : integer;cch : integer;code : integer) : integer{$IFDEF WIN32} stdcall; {$ELSE} ; export; {$ENDIF} begin result := 0; end;procedure TForm1.FormCreate(Sender: TObject); begin OriginalWordBreakProc := Pointer( SendMessage(Memo1.Handle, EM_GETWORDBREAKPROC, 0, 0));{$IFDEF WIN32} NewWordBreakProc := @MyWordBreakProc;{$ELSE}NewWordBreakProc := MakeProcInstance(@MyWordBreakProc, hInstance);{$ENDIF} SendMessage(Memo1.Handle, EM_SETWORDBREAKPROC, 0, longint(NewWordBreakProc));end;procedure TForm1.FormDestroy(Sender: TObject); begin SendMessage(Memo1.Handle, EM_SETWORDBREAKPROC, 0, longint(@OriginalWordBreakProc));{$IFNDEF WIN32}FreeProcInstance(NewWordBreakProc);{$ENDIF} end;
Наверх к содержанию
Вопрос:
Можно ли скопировать группу файлов, используя стандартный диалог с
анимацией Копирование Файлов, который использует "Проводник" (Explorer)?
Ответ:
В следующем примере используется функция SHFileOperation для копирования
группы файлов и показа анимированного диалога. Вы можете использовать также
следующие флаги для копирования, удаления, переноса и переименования файлов.
TO_COPY FO_DELETE FO_MOVE FO_RENAME
Примечание: буфер, содержащий имена файлов для копирования должен заканчиваться
двумя нулевыми символами.
Пример:
uses ShellAPI;procedure TForm1.Button1Click(Sender: TObject); varFo : TSHFileOpStruct;buffer : array[0..4096] of char;p: pchar;begin FillChar(Buffer, sizeof(Buffer), #0); p := @buffer; p := StrECopy(p, 'C:\DownLoad\1.ZIP') + 1; p := StrECopy(p, 'C:\DownLoad\2.ZIP') + 1; p := StrECopy(p, 'C:\DownLoad\3.ZIP') + 1; StrECopy(p, 'C:\DownLoad\4.ZIP');FillChar(Fo, sizeof(Fo), #0); Fo.Wnd := Handle; Fo.wFunc := FO_COPY; Fo.pFrom := @Buffer; Fo.pTo := 'D:\'; Fo.fFlags := 0; if ((SHFileOperation(Fo) <> 0) or (Fo.fAnyOperationsAborted <> false)) then ShowMessage('Cancelled') end;
Наверх к содержанию
Вопрос:
Использование FindFirst для поиска файлов.
Ответ:
begin Result := SysUtils.FindFirst(Path, Attr, SearchRec); while Result = 0 do begin ProcessSearchRec(SearchRec); Result := SysUtils.FindNext(SearchRec); end;SysUtils.FindClose(SearchRec); end;
Наверх к содержанию
Вопрос:
Как получить дескриптор окна другого приложения и сделать его активным?
Ответ:
Использование фуекции Windows API FindWindow() - простейший способ
нахождение окна, при условии, что известен его заголовок или имя оконного
класса. Если Вам известна только часть заголовка окна (например 'Netscape
- ' + 'какой-то неизвестный URL'), Вам нужно использовать функцию EnumWindows()
для получения всех окон, затем вызывать функцию GetWindowsText() и GetClassName
для поиска нужного окна. Следующий пример находит первое окно, содержащее
совпадающую часть заголовка окна и полностью совпадающее название оконного
класса (если он задан) и делает это окно активным.
type PFindWindowStruct = ^TFindWindowStruct; TFindWindowStruct = record Caption : string; ClassName : string; WindowHandle : THandle; end;function EnumWindowsProc(hWindow : hWnd;lParam : LongInt) : Bool {$IFDEF Win32} stdcall; {$ELSE} ; export; {$ENDIF} var lpBuffer : PChar; WindowCaptionFound : bool; ClassNameFound : bool;begin GetMem(lpBuffer, 255); Result := True; WindowCaptionFound := False; ClassNameFound := False;try if GetWindowText(hWindow, lpBuffer, 255) > 0 then if Pos(PFindWindowStruct(lParam).Caption, StrPas(lpBuffer)) > 0then WindowCaptionFound := true;if PFindWindowStruct(lParam).ClassName = '' then ClassNameFound := True else if GetClassName(hWindow, lpBuffer, 255) > 0 then if Pos(PFindWindowStruct(lParam).ClassName, StrPas(lpBuffer))> 0 then ClassNameFound := True;if (WindowCaptionFound and ClassNameFound) then begin PFindWindowStruct(lParam).WindowHandle := hWindow; Result := False; end;finally FreeMem(lpBuffer, sizeof(lpBuffer^)); end; end;function FindAWindow(Caption : string;ClassName : string) : THandle; var WindowInfo : TFindWindowStruct;begin with WindowInfo do begin Caption := Caption; ClassName := ClassName; WindowHandle := 0; EnumWindows(@EnumWindowsProc, LongInt(@WindowInfo)); FindAWindow := WindowHandle; end; end;procedure TForm1.Button1Click(Sender: TObject); var TheWindowHandle : THandle; begin TheWindowHandle := FindAWindow('Netscape - ', ''); if TheWindowHandle = 0 then ShowMessage('Window Not Found!') else BringWindowToTop(TheWindowHandle); end;
Наверх к содержанию
Вопрос:
Как написать программу не имеющую ни одной формы?
Ответ:
Создайте новое приложение, затем удалите из проекта все unitы - (Delphi
3 - View - Project Manager)
(Delphi 4 - Project - Remove from project)
Откройте файл проекта
(Delphi 3 - View - Project Source)
(Delphi 3 - Project - View Source)
и отредактируйте его так как приведино ниже.
Пример:
program Project1;{$R *.RES}uses SysUtils;var f : TextFile;begin AssignFile(f, 'TestFile.Txt'); ReWrite(f); Writeln(f, 'Test'); Close(f); end.
Наверх к содержанию
Вопрос:
Почему возникает ошибка при передаче параметров типа boolean равного
True в некоторые внешней функции
Ответ:
В Delphi 3 значение "True" для типов ByteBool, WordBool LongBool представляется
как -1 для совместимости с Microsoft Visual Basic. Многие компиляторы представляют
"True" как либо "не нуль" либо 1. При передаче параметров в не Visual Basic-приложения
Вам следует придерживаться следующей техники во избежание несовместимости:
LongBool(Abs(True));
При приеме значений типа boolean из внешних программ Вам следует всегда
проверять его на значение "False". Эта техника всегда работает, поскольку
"False" всегда представляется нулем.
if BoolValPassed <> False then DoSomething.
Наверх к содержанию
Вопрос:
Как получить длинное имя файла или каталога, зная короткое имя?
Ответ:
Используйте Win32_Find_Data поле TSearchRec.
Пример:
procedure TForm1.Button1Click(Sender: TObject); var SearchRec : TSearchRec; Success : integer; begin Success := SysUtils.FindFirst('C:\DownLoad\dial-u~1.htm', faAnyFile, SearchRec); if Success = 0 then begin ShowMessage(SearchRec.FindData.CFileName); end; SysUtils.FindClose(SearchRec); end;
Наверх к содержанию
Вопрос:
Как временно отключить range checking для участка программы, а затем
вновь вклчить его?
Ответ:
Можно сделать это, используя "IFOPT" и "DEFINE".
type PSomeArray = ^TSomeArray; TSomeArray = array[0..0] of integer;procedure TForm1.Button1Click(Sender: TObject); var p : PSomeArray; i : integer;begin {$IFOPT R+} {$DEFINE CKRANGE} {$R-} {$ENDIF} GetMem(p, sizeof(integer) * 200); try for i := 1 to 200 do p[i] := i; finally FreeMem(p, sizeof(integer) * 200); end;{$IFDEF CKRANGE} {$UNDEF CKRANGE} {$R+} {$ENDIF} end;
Наверх к содержанию
Вопрос:
Как получить имя файла и путь локальной таблицы?
Ответ:
Следующий пример взят из файла BDE32.HLP Borland/CommonFiles/BDE directory:
implementation{$R *.DFM}uses DbiTypes, DbiProcs;function fDbiFormFullName(Tbl: TTable): String; var Props: CurProps; Buffer1 : array[0..DBIMAXPATHLEN] of char; Buffer2 : array[0..DBIMAXPATHLEN] of char; begin Check(DbiGetCursorProps(Tbl.Handle,Props)); StrPCopy(Buffer1, Tbl.TableName); Check(DbiFormFullName(Tbl.DBHandle, @Buffer1, Props.szTableType, @Buffer2)); Result := StrPas(Buffer2); end;procedure TForm1.Button1Click(Sender: TObject); begin Memo1.Lines.Add(fDbiFormFullName(Table1)); end;римечание: Таблица должна быть открытой. Работает с локальными таблицами.
Наверх к содержанию
Вопрос:
Как получить дескриптор панели задач (TaskBar)?
Ответ:
hTaskbar := FindWindow('Shell_TrayWnd', Nil );
Наверх к содержанию
Вопрос:
Как из программы запустить Screen Saver?
Ответ:
Представленная ниже функция демонстрирует как это сделать
function TurnScreenSaverOn : bool; var b : bool; begin result := false; if SystemParametersInfo(SPI_GETSCREENSAVEACTIVE, 0, @b, 0) <> true then exit; if not b then exit; PostMessage(GetDesktopWindow, WM_SYSCOMMAND, SC_SCREENSAVE, 0); result := true; end;
Наверх к содержанию
Вопрос:
Как выяснить установлены ли в системе шрифты TrueType?
Ответ:
function IsTrueTypeAvailable : bool; var{$IFDEF WIN32} rs : TRasterizerStatus;{$ELSE} rs : TRasterizer_Status;{$ENDIF} begin result := false; if not GetRasterizerCaps(rs, sizeof(rs)) then exit; if rs.WFlags and TT_AVAILABLE <> TT_AVAILABLE then exit; if rs.WFlags and TT_ENABLED <> TT_ENABLED then exit; result := true; end;
Наверх к содержанию
Вопрос:
Как переслать файл в Мусорную Корзину?
Ответ:
Используйте функцию SHFileOperation().
uses ShellAPI;procedure SendToRecycleBin(FileName: string); var SHF: TSHFileOpStruct; begin with SHF do begin Wnd := Application.Handle; wFunc := FO_DELETE; pFrom := PChar(FileName); fFlags := FOF_SILENT or FOF_ALLOWUNDO; end; SHFileOperation(SHF); end;procedure TForm1.Button1Click(Sender: TObject); begin SendToRecycleBin('c:\DownLoad\Test.gif'); end;
Наверх к содержанию
Вопрос:
Как выяснить запущен ли Delphi / C++ Builder?
Ответ:
Используйте функцию FindWindow. (Класс главного окна Delphi / C++ Builder
- TAppBuilder)
if FindWindow('TAppBuilder', Nil) <> 0 Then ShowMessage('Delphi and or C++ Builder is running');
Наверх к содержанию
Вопрос:
Как програмно выяснить версию Windows?
Ответ:
{$IFDEF WIN32} function GetVersionEx(lpOs : pointer) : BOOL; stdcall;external 'kernel32' name 'GetVersionExA'; {$ENDIF}procedure GetWindowsVersion(var Major : integer; var Minor : integer); var{$IFDEF WIN32} lpOS, lpOS2 : POsVersionInfo;{$ELSE} l : longint;{$ENDIF} begin{$IFDEF WIN32}GetMem(lpOS, SizeOf(TOsVersionInfo));lpOs^.dwOSVersionInfoSize := SizeOf(TOsVersionInfo);while getVersionEx(lpOS) = false do beginGetMem(lpos2, lpos^.dwOSVersionInfoSize + 1);lpOs2^.dwOSVersionInfoSize := lpOs^.dwOSVersionInfoSize + 1;FreeMem(lpOs, lpOs^.dwOSVersionInfoSize);lpOS := lpOs2;end;Major := lpOs^.dwMajorVersion;Minor := lpOs^.dwMinorVersion;FreeMem(lpOs, lpOs^.dwOSVersionInfoSize);{$ELSE} l := GetVersion; Major := LoByte(LoWord(l)); Minor := HiByte(LoWord(l));{$ENDIF} end;procedure TForm1.Button1Click(Sender: TObject); var Major : integer; Minor : integer; begin GetWindowsVersion(Major, Minor); Memo1.Lines.Add(IntToStr(Major)); Memo1.Lines.Add(IntToStr(Minor)); end;
Наверх к содержанию
Вопрос:
Как узнать переменные окружения (environment variable) DOS, например
path?
Ответ:
Windows API - функцияGetDOSEnvironment() для Win16 и GetEnvironmentStrings() для Win32.
Пример:
procedure TForm1.Button1Click(Sender: TObject); var p : pChar; begin Memo1.Lines.Clear; Memo1.WordWrap := false;{$IFDEF WIN32} p := GetEnvironmentStrings;{$ELSE} p := GetDOSEnvironment;
{$ENDIF}
while p^ <> #0 do begin
Memo1.Lines.Add(StrPas(p));
inc(p, lStrLen(p) + 1);
end;
{$IFDEF WIN32}
FreeEnvironmentStrings(p);
{$ENDIF}
end;
Наверх к содержанию
Вопрос:
Как рисовать непосредственно на Рабочем столе?
Ответ:
Пример:
procedure TForm1.Button1Click(Sender: TObject);
var
dc : hdc;
begin
dc := GetDc(0);
MoveToEx(Dc, 0, 0, nil);
LineTo(Dc, 300, 300);
ReleaseDc(0, Dc);
end;
Наверх к содержанию
Вопрос:
Как определить каталог Windows?
Ответ:
Вызовите функцию GetWindowsDirectory(). Если Вас интересует каталог
System, вызовите функцию GetSystemDirectory().
Пример:
{$IFNDEF WIN32}
const MAX_PATH = 144;
{$ENDIF}
procedure TForm1.Button1Click(Sender: TObject);
var
a : Array[0..MAX_PATH] of char;
begin
GetWindowsDirectory(a, sizeof(a));
ShowMessage(StrPas(a));
GetSystemDirectory(a, sizeof(a));
ShowMessage(StrPas(a));
end;
Наверх к содержанию
Вопрос:
Как определить размер рабочего стола без Тaskbar'а?
Ответ:
Воспользуйтесь функцией SystemParametersInfo(), переслав ей в качестве
параметров - SPI_GETWORKAREA и адрес структуры типа TRect, куда будут передан
полученный результат.
Пример:
procedure TForm1.Button1Click(Sender: TObject);
var
r : TRect;
begin
SystemParametersInfo(SPI_GETWORKAREA,
0,
@r,
0);
Memo1.Lines.Add(IntToStr(r.Top));
Memo1.Lines.Add(IntToStr(r.Left));
Memo1.Lines.Add(IntToStr(r.Bottom));
Memo1.Lines.Add(IntToStr(r.Right));
end;
Наверх к содержанию
Вопрос:
Как спрятать Панель Задач Windows (Task Bar)?
Ответ:
Вначале необходимо вызвать функцию FindWindow(), чтобы определить handle
TaskBar. Затем вызвите функцию ShowWindow(), передав ей в качестве параметра
костанту SW_HIDE.
Пример:
procedure TForm1.Button1Click(Sender: TObject);
var
hTaskBar : THandle;
begin
hTaskbar := FindWindow('Shell_TrayWnd', Nil);
ShowWindow(hTaskBar, SW_HIDE);
end;
procedure TForm1.Button2Click(Sender: TObject);
var
hTaskBar : THandle;
begin
hTaskbar := FindWindow('Shell_TrayWnd', Nil);
ShowWindow(hTaskBar, SW_SHOWNORMAL);
end;
Наверх к содержанию
Вопрос:
Как определить подключен ли компюетер к сети.
Ответ:
Воспользуйтесь функцией GetSystemMetrics(), переслав ей флаг SM_NETWORK.
Пример:
procedure TForm1.Button1Click(Sender: TObject);
begin
if GetSystemMetrics(SM_NETWORK) AND $01 = $01 then
ShowMessage('Machine is attached to network') else
ShowMessage('Machine is not attached to network');
end;
Наверх к содержанию
Вопрос:
Как добавить документ в меню ПУСК - ДОКУМЕНТЫ?
Ответ:
Используйте функцию SHAddToRecentDocs.
Пример:
uses ShlOBJ;
procedure TForm1.Button1Click(Sender: TObject);
var
s : string;
begin
s := 'C:\DownLoad\ntkfaq.html';
SHAddToRecentDocs(SHARD_PATH, pChar(s));
end;
Наверх к содержанию
Вопрос:
Как после записи в ini-файл сбросить cache на диск, чтоб задействовать
изменения?
Ответ:
Вызовите функцию WriteProfileString() или WritePrivateProfileString(),
передав ей в качестве параметров секции, ключа и строки - nil.
Пример:
WriteProfileString(nil, nil, nil);
WritePrivateProfileString(nil, nil, nil, FileName);
Наверх к содержанию
Вопрос:
Как с помощью Проводника открыть конкретный каталог?
Ответ:
Пример:
uses ShellApi;
procedure TForm1.Button1Click(Sender: TObject);
begin
ShellExecute(0,
'explore',
'C:\WINDOWS',
nil,
nil,
SW_SHOWNORMAL);
end;
Наверх к содержанию
Вопрос:
Как запустить аплет Панели управления?
Ответ:
Запустить аплет Панели управления можно вызвав функцию WinExec, для
выполнения файла control.exe, которому передано имя аплета. Обычно аплеты
панели управления расположены в каталоге System Windows и имеют расширение
.cpl.
Пример:
procedure TForm1.Button1Click(Sender: TObject);
begin
WinExec('C:\WINDOWS\CONTROL.EXE TIMEDATE.CPL',
sw_ShowNormal);
WinExec('C:\WINDOWS\CONTROL.EXE MOUSE',
sw_ShowNormal);
WinExec('C:\WINDOWS\CONTROL.EXE PRINTERS',
sw_ShowNormal);
end;
Наверх к содержанию
Вопрос:
Как открыть URL браузером, установленным по умолчанию?
Ответ:
Используйте функцию ShellExecute.
Пример:
uses ShellAPI;
procedure TForm1.Button1Click(Sender: TObject);
begin
ShellExecute(Form1.Handle,
nil,
'http://www.borland.com',
nil,
nil,
SW_SHOWNORMAL);
end;
Наверх к содержанию
Вопрос:
Как стереть ехе-файл во время его исполнения?
Ответ:
Это не возможно. Вы можете стереть его во время следующего запуска
Windows, добавив ключ RunOnce:
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce
Пример:
uses
Registry;
procedure TForm1.Button1Click(Sender: TObject);
var
reg: TRegistry;
begin
reg := TRegistry.Create;
with reg do begin
RootKey := HKEY_LOCAL_MACHINE;
LazyWrite := false;
OpenKey('Software\Microsoft\Windows\CurrentVersion\RunOnce',
false);
WriteString('Delete Me!','command.com /c del FILENAME.EXT');
CloseKey;
free;
end;
end;
Наверх к содержанию
Вопрос:
Как програмноинсталировать шрифты TrueType?
Ответ:
Скопируйте файл шрифта в директорию Windows\Fonts, и добавьте строку
с именем шрифта и его расположением в разделе "'Software\Microsoft\Windows\CurrentVersion\Fonts".
Вызовите функцию AddFontRecource(), а затем передайте системе сообщение
WM_FONTCHANGE. И наконец, для удоления установленного шрифта, вызовите
функцию RemoveFontRecource(), а затем передайте системе сообщение WM_FONTCHANGE.
Пример:
uses Registry;
procedure TForm1.Button1Click(Sender: TObject);
var
reg: TRegistry;
b : bool;
begin
CopyFile('C:\DOWNLOAD\FP000100.TTF',
'C:\WINDOWS\FONTS\FP000100.TTF', b);
reg := TRegistry.Create;
reg.RootKey := HKEY_LOCAL_MACHINE;
reg.LazyWrite := false;
reg.OpenKey('Software\Microsoft\Windows\CurrentVersion\Fonts',
false);
reg.WriteString('TESTMICR (TrueType)','FP000100.TTF');
reg.CloseKey;
reg.free;
{Add the font resource}
AddFontResource('c:\windows\fonts\FP000100.TTF');
SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);
{Remove the resource lock}
RemoveFontResource('c:\windows\fonts\FP000100.TTF');
SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);
end;
Наверх к содержанию
Вопрос:
Как получить список часовых поясов?
Ответ:
Пример:
uses Registry;
procedure TForm1.Button1Click(Sender: TObject);
var
reg : TRegistry;
ts : TStrings;
i : integer;
begin
reg := TRegistry.Create;
reg.RootKey := HKEY_LOCAL_MACHINE;
reg.OpenKey(
'SOFTWARE\Microsoft\Windows\CurrentVersion\Time Zones',
false);
if reg.HasSubKeys then begin
ts := TStringList.Create;
reg.GetKeyNames(ts);
reg.CloseKey;
for i := 0 to ts.Count -1 do begin
reg.OpenKey(
'SOFTWARE\Microsoft\Windows\CurrentVersion\Time Zones\' +
ts.Strings[i],
false);
Memo1.Lines.Add(ts.Strings[i]);
Memo1.Lines.Add(reg.ReadString('Display'));
Memo1.Lines.Add(reg.ReadString('Std'));
Memo1.Lines.Add(reg.ReadString('Dlt'));
Memo1.Lines.Add('----------------------');
reg.CloseKey;
end;
ts.Free;
end else
reg.CloseKey;
reg.free;
end;
Наверх к содержанию
Вопрос:
Какие значения возвращает функция GetTimeZoneInformation()?
Ответ:
const TIME_ZONE_ID_UNKNOWN = 0;
const TIME_ZONE_ID_STANDARD = 1;
const TIME_ZONE_ID_DAYLIGHT = 2;
Наверх к содержанию
Вопрос:
Как сделать прозрачным фон текста?
Ответ:
Используйте функцию SetBkMode().
Пример:
procedure TForm1.Button1Click(Sender: TObject);
var
OldBkMode : integer;
begin
with Form1.Canvas do begin
Brush.Color := clRed;
FillRect(Rect(0, 0, 100, 100));
Brush.Color := clBlue;
TextOut(10, 20, 'Not Transparent!');
OldBkMode := SetBkMode(Handle, TRANSPARENT);
TextOut(10, 50, 'Transparent!');
SetBkMode(Handle, OldBkMode);
end;
end;
Наверх к содержанию
Вопрос:
Как получить информацию о версии файла?
Ответ:
Для этого необходимо вызвать несколько функций API. В приведеннном
ниже примере проверяется версия shell32.dll. Функция возвращает значение
True - если версия DLL больше или равна 4.71
function TForm1.CheckShell32Version: Boolean;
procedure GetFileVersion(FileName: string; var Major1, Major2,
Minor1, Minor2: Integer);
{ Helper function to get the actual file version information }
var
Info: Pointer;
InfoSize: DWORD;
FileInfo: PVSFixedFileInfo;
FileInfoSize: DWORD;
Tmp: DWORD;
begin
// Get the size of the FileVersionInformatioin
InfoSize := GetFileVersionInfoSize(PChar(FileName), Tmp);
// If InfoSize = 0, then the file may not exist, or
// it may not have file version information in it.
if InfoSize = 0 then
raise Exception.Create('Can''t get file version information for '
+ FileName);
// Allocate memory for the file version information
GetMem(Info, InfoSize);
try
// Get the information
GetFileVersionInfo(PChar(FileName), 0, InfoSize, Info);
// Query the information for the version
VerQueryValue(Info, '\', Pointer(FileInfo), FileInfoSize);
// Now fill in the version information
Major1 := FileInfo.dwFileVersionMS shr 16;
Major2 := FileInfo.dwFileVersionMS and $FFFF;
Minor1 := FileInfo.dwFileVersionLS shr 16;
Minor2 := FileInfo.dwFileVersionLS and $FFFF;
finally
FreeMem(Info, FileInfoSize);
end;
end;
var
tmpBuffer: PChar;
Shell32Path: string;
VersionMajor: Integer;
VersionMinor: Integer;
Blank: Integer;
begin
tmpBuffer := AllocMem(MAX_PATH);
// Get the shell32.dll path
try
GetSystemDirectory(tmpBuffer, MAX_PATH);
Shell32Path := tmpBuffer + '\shell32.dll';
finally
FreeMem(tmpBuffer);
end;
// Check to see if it exists
if FileExists(Shell32Path) then
begin
// Get the file version
GetFileVersion(Shell32Path, VersionMajor, VersionMinor, Blank, Blank);
// Do something, such as require a certain version
// (such as greater than 4.71)
if (VersionMajor >= 4) and (VersionMinor >= 71) then
Result := True
else
Result := False;
end
else
Result := False;
end;
Наверх к содержанию
Вопрос:
Как держать приложение в минимизированном виде?
Ответ:
Установите свойство WindowState в Minimized. Создайте обработчик сообщения
WM_QueryOpen.
Пример:
{Place this code in the private section of the Form declaration}
procedure WMQueryOpen(VAR Msg : TWMQueryOpen); message WM_QUERYOPEN;
{Place this code in the Form implementation section}
procedure TForm1.WMQueryOpen(VAR Msg : TWMQueryOpen);
begin
Msg.Result := 0;
end;
Наверх к содержанию
Вопрос:
при вызове функции RegisterClass я получаю ошибку: "Incompatible types:
'TPersistantClass' and 'TWndClassA'"
Ответ:
Функция RegisterClass() обьявлена в модулях Classes и Windows unit.
Чтобы вызвать функцию из модуля Windows просто добавте префикс "Windows."
Пример:
procedure TForm1.Button1Click(Sender: TObject);
wc : TWndClass;
begin
Windows.RegisterClass(wc)
end;
Наверх к содержанию
Вопрос:
Как принять файлы, брошенные на мою форму по drag & drop
Ответ:
Нужно сообщить Windows, что ваша форма принимает файлы по drag &
drop с помощью функции Shell API DragAcceptFiles.(в обработчике события
form create) Затем нужно реагироавть на сообытия drag & drop чтобы
принять файлы. (см. пример)
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
private
procedure WMDROPFILES(var Message: TWMDROPFILES);
message WM_DROPFILES;
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
uses ShellApi;
procedure TForm1.FormCreate(Sender: TObject);
begin
{Let Windows know we accept dropped files}
DragAcceptFiles(Form1.Handle, True);
end;
procedure TForm1.WMDROPFILES(var Message: TWMDROPFILES);
var
NumFiles : longint;
i : longint;
buffer : array[0..255] of char;
begin
{How many files are being dropped}
NumFiles := DragQueryFile(Message.Drop,
-1,
nil,
0);
{Accept the dropped files}
for i := 0 to (NumFiles - 1) do begin
DragQueryFile(Message.Drop,
i,
@buffer,
sizeof(buffer));
Form1.Memo1.Lines.Add(buffer);
end;
end;
end.
Наверх к содержанию
Вопрос:
Как создать задержку не подвешивая систему без компонента TTimer ?
Ответ:
В примере используется вызов Application.ProcessMessages для того,
чтобы Windows обрабатывал сообщения во время цикла задержки.
procedure Delay(ms : longint);
var
TheTime : LongInt;
begin
TheTime := GetTickCount + ms;
while GetTickCount < TheTime do
Application.ProcessMessages;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage('Start Test');
Delay(2000);
ShowMessage('End Test');
end;
Наверх к содержанию
Вопрос:
Как програмно перезагрузить Windows? Ответ:
Используйте функцию ExitWindows(). В качестве первого параметра ей передается она из трех констант:
EW_RESTARTWINDOWS
EW_REBOOTSYSTEM
EW_EXITANDEXECAPP
Второй параметр используется для перезагрузки компьютера в режиме эмуляции
MS DOS. Пример:
ExitWindows(EW_RESTARTWINDOWS, 0 );
Наверх к содержанию
|