keybd_event(Ord(Chr(32)),0,0,0);
keybd_event(Ord(Chr(32)),0,KEYEVENTF_KEYUP,0);
//uwaga: numer klawisza (w przykładzie 32 oznacza spację) sprawdzić można wywołując procedurę OnKeyDown dla Memo:
procedure TForm1.Memo1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
ShowMessage(IntToStr(Key));
end;
var MainHook: hHook;
function KeyHook(code: Integer; wPar : wParam; lPar : lParam): Longint; StdCall;
var kState: TKeyboardState;
begin
GetKeyboardState(kState); if (kState[32] and $80) < > 0
then ShowMessage('Wcisnąłeś spację');
if (kState[65] and kState[66] and not kState[67] and $80) < > 0
then ShowMessage('Wcisnąłeś jednocześnie klawisze A i B przy czym klawisz C nie był wciśnięty');
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
MainHook:=SetWindowsHookEx(WH_Keyboard,KeyHook,hInstance,0);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
UnhookWindowsHookEx(MainHook);
end;
//uwaga: numer klawisza (w przykładzie 32 oznacza spację) sprawdzić można wywołując procedurę OnKeyDown dla Memo:
procedure TForm1.Memo1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
ShowMessage(IntToStr(Key));
end;
private
procedure WMHotKey(var Msg : TMessage); message WM_HOTKEY;
procedure TForm1.FormCreate(Sender: TObject);
begin
RegisterHotKey(Handle,$0001,0,VK_SPACE); //Space
RegisterHotKey(Handle,$0002,MOD_ALT,VK_A); //Alt+A=ą
RegisterHotKey(Handle,$0003,MOD_SHIFT,VK_0); //Shift+2=@
RegisterHotKey(Handle,$0004,0,VK_F12); //F12
end;
procedure TForm1.WMHotKey(var Msg: TMessage);
begin
if Msg.wParam=$0001 then ShowMessage('Wybrano spację');
if Msg.wParam=$0002 then ShowMessage('Wybrano literę ą');
if Msg.wParam=$0003 then ShowMessage('Wybrano znak @');
if Msg.wParam=$0004 then ShowMessage('Wybrano F12');
end;
//uwaga: 1. reakcja domyślna (na przykład zrobienie odstepu dla kalwisza Space) po nadpisaniu nie zostanie wywołana
2. niemożliwe jest nadpisanie tą metodą zdarzenia wywołango dla kombinacji kalwiszy Alt+Ctrl+Del
private
procedure WMHotKey(var Msg : TMessage); message WM_HOTKEY;
procedure TForm1.FormCreate(Sender: TObject);
begin
RegisterHotKey(Handle,$0001,0,VK_SNAPSHOT);
end;
procedure TForm1.WMHotKey(var Msg: TMessage);
begin
if Msg.wParam=$0001 then begin
//tu można wpisać instrukcję wykonywaną po wciśnięciu klawisza PrintScreen
end; end;
function TForm1.GdzieWindows: String;
var wDir: array [0..255] of Char;
begin
GetWindowsDirectory(wDir,SizeOf(wDir));
Result:=wDir;
end;
function TForm1.GdzieSystem: String;
var wDir: array [0..255] of Char;
begin
GetSystemDirectory(wDir,SizeOf(wDir)); Result:=wDir;
end;
Do symulacji kliknięć mysz± służy funkcja WinAPI mouse_event:
SetCursorPos(x, y); // przedtem dane (ustawienie) dla kursora - pozycja x,y
mouse_event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_LEFTDOWN, x, y, 0, 0);
mouse_event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_LEFTUP, x, y, 0, 0);
co daje symulację kliknięcia lewym przyciskiem myszy w punkcie (x,y), natomiast
do symulacji klawiatury używamy funkcji keybd_event:
keybd_event(VK_UP, 0, 0, 0);
keybd_event(VK_UP, 0, KEYEVENTF_KEYUP, 0);
Co powoduje symulację kliknięcia klawisza strzałki w górę.
unit Sernumu;
interface
uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls;
type TMediaID = Record
InfoLevel : Word; SerialNumber : LongInt;
VolumeLabel : Array[0..10] of Char; SysName : Array[0..7] of Char;
End;
TForm1 = class(TForm)
Button1: TButton; Label1: TLabel;
Label2: TLabel; Label3: TLabel;
procedure Button1Click(Sender: TObject);
private { Private declarations }
MediaID : TMediaID;
public { Public declarations }
end;
var Form1: TForm1;
implementation {$R *.DFM}
type DPMIRegisters = record
DI : LongInt; SI : LongInt; BP : LongInt; Reserved : LongInt;
BX : LongInt; DX : LongInt; CX : LongInt; AX : LongInt;
Flags : Word; ES : Word; DS : Word; FS : Word; GS : Word;
IP : Word; CS : Word; SP : Word; SS : Word;
end;
function RealIntr(IntNo : Byte; var Regs : DPMIRegisters) : Word; Assembler;
asm
xor bx,bx
mov bl,IntNo
xor cx,cx {StackWords = 0}
les di,Regs
mov ax,0300h
int 31h
jc @@ExitPoint
xor ax,ax
@@ExitPoint:
end;
function GetDiskInfo(Drive : Word; var MediaID : TMediaID) : Boolean;
type tLong = Record LoWord, HiWord : Word;
End;
var Regs : DPMIRegisters; dwAddress : LongInt; Address : tLong absolute dwAddress;
begin
Result := False; FillChar(MediaID, SizeOf(MediaID), 0);
dwAddress := GlobalDosAlloc(SizeOf(MediaID)); { two paragraphs of DOS memory }
if dwAddress = 0 then { address is zero if error occurred }
exit;
With Regs do begin
bx := Drive;
cx := $66;
ds := Address.HiWord;
ax := $6900;
dx := 0;
es := 0;
flags := 0;
end;
If RealIntr($21, Regs) < > 0 Then Exit;
Move(ptr(Address.LoWord, 0)^, MediaID, SizeOf(MediaID));
GlobalDosFree(Address.LoWord) { free DOS memory block }
Result := True;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
GetDiskInfo(1, MediaID); With MediaID do Begin
Label1.Caption := IntToHex(SerialNumber, 8);
Label2.Caption := VolumeLabel; Label3.Caption := SysName; End;
end;
end.
type
MIDPtr = ^MIDRec; MIDRec = Record InfoLevel: word; SerialNum: LongInt;
VolLabel: Packed Array [0..10] of Char;
FileSysType: Packed Array [0..7] of Char;
end;
function GetDriveSerialNum(MID: MIDPtr; drive: Word): Boolean; assembler;
asm
push DS { Just for safety, I dont think its really needed }
mov ax,440Dh { Function Get Media ID }
mov bx,drive { drive no (0-Default, 1-A ...) }
mov cx,0866h { category and minor code }
lds dx,MID { Load pointeraddr. }
call DOS3Call { Supposed to be faster than INT 21H }
jc @@err
mov al,1 { No carry so return TRUE }
jmp @@ok
@@err:
mov al,0 { Carry set so return FALSE }
@@ok:
pop DS { Restore DS, were not supposed to change it }
end;
procedure TForm1.NrBtnClick(Sender: TObject);
var Info: MIDRec;
begin
Info.InfoLevel:=0; { Information Level }
If GetDriveSerialNum(@Info,0) then { Do something with it... }
ListBox.Items.Add(IntToStr(Info.SerialNum)+' '+Info.VolLabel);
end;
function GetHardDiskSerial(const DriveLetter: Char): string;
var NotUsed: DWORD; VolumeFlags: DWORD;
VolumeInfo: array[0..MAX_PATH] of Char;
VolumeSerialNumber: DWORD;
begin
GetVolumeInformation(PChar(DriveLetter + ':\'), nil, SizeOf(VolumeInfo), @VolumeSerialNumber, NotUsed,
VolumeFlags, nil, 0);
Result := Format('Label = %s VolSer = %8.8X', [VolumeInfo, VolumeSerialNumber])
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(GetHardDiskSerial('c'));
end;
function GetComputerName: string;
var buffer: array[0..MAX_COMPUTERNAME_LENGTH + 1] of Char; Size: Cardinal;
begin
Size := MAX_COMPUTERNAME_LENGTH + 1;
Windows.GetComputerName(@buffer, Size);
Result := StrPas(buffer);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(GetComputerName);
end;
//ustawienie nazwy komputera...
function SetComputerName(AComputerName: string): Boolean;
var ComputerName: array[0..MAX_COMPUTERNAME_LENGTH + 1] of Char; Size: Cardinal;
begin
StrPCopy(ComputerName, AComputerName);
Result := Windows.SetComputerName(ComputerName);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
if SetComputerName('NewComputerName') then
ShowMessage('Computer Name Reset Setting will be used at next startup.')
else ShowMessage('Computer Name Not Reset');
end;
procedure TForm1.Button1Click(Sender: TObject);
var memory: TMemoryStatus;
begin
memory.dwLength := SizeOf(memory); GlobalMemoryStatus(memory);
ShowMessage('Total Arbeitsspeicher/Total memory: ' +
IntToStr(memory.dwTotalPhys) + ' Bytes');
ShowMessage('Freier Arbeitsspeicher/Available memory: ' +
IntToStr(memory.dwAvailPhys) + ' Bytes');
end;
Oczywiście - drukarka musi byc włączona
var FDevice: PChar; FDriver: PChar; FPort: PChar;
DeviceMode: THandle; DevMode: PDeviceMode;
procedure OpenThePrinterDevice;
var Driver_Info2: PDriverInfo2; Retrieved: dword; hPrinter: THandle;
begin
Printer().GetPrinter(FDevice, FDriver, FPort, DeviceMode);
if DeviceMode = 0 then
Printer().GetPrinter(FDevice, FDriver, FPort, DeviceMode); OpenPrinter(FDevice, hPrinter, nil);
GetMem(Driver_Info2, 255);
GetPrinterDriver(hPrinter, nil, 2, Driver_info_2, 255, Retrieved);
StrLCopy(FDriver, PChar(ExtractFileName(StrPas(Driver_Info2^.PDriverPath)) + #0), 63);
FreeMem(Driver_info_2, 255); DevMode := GlobalLock(DeviceMode);
end;
function IsKeyToggled( VirtKey: Integer): Boolean;
begin
Result := (GetKeyState( VirtKey ) and $0001) < > 0;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
chkCaps.Checked := IsKeyToggled( VK_CAPITAL );
chkNum.Checked := IsKeyToggled( VK_NUMLOCK );
chkScroll.Checked := IsKeyToggled( VK_SCROLL );
chkIns.Checked := IsKeyToggled( VK_INSERT );
end;
Ponizsza procedura otwiera/zamyka szuflade napedu CD w oparciu o podane
parametry, co pozwala na wybranie napedu jesli sa dwa lub wiecej w danym
komputerze.
uses MMSystem;
procedure OpenCloseCD(Drive: String; OpenCD: Boolean);
var OpenParm: TMCI_Open_Parms;
begin
OpenParm.dwCallback := 0; OpenParm.lpstrDeviceType := 'CDAudio';
OpenParm.lpstrElementName := PChar(Drive); {Drive musi byc w formacie "X:"}
if OpenCD then begin {Otwieranie szuflady}
mciSendCommand(0, MCI_OPEN, MCI_OPEN_ELEMENT or MCI_OPEN_TYPE, Longint(@OpenParm));
mciSendCommand(OpenParm.wDeviceID, MCI_SET, MCI_SET_DOOR_OPEN, 0);
end else begin {zamykanie szuflady}
mciSendCommand(0, MCI_OPEN, MCI_OPEN_ELEMENT or MCI_OPEN_TYPE, Longint(@OpenParm));
mciSendCommand(OpenParm.wDeviceID, MCI_SET, MCI_SET_DOOR_CLOSED, 0);
end; {zamykanie MCI, bez tego kolejna proba otwarcia/zamkniecia szuflady zakonczylaby sie niepowodzeniem!!! }
mciSendCommand(OpenParm.wDeviceID, MCI_CLOSE, MCI_NOTIFY, Longint(@OpenParm));
OpenCD := not OpenCD;
end;
Po pierwsze musisz dodać do listy uses nazwę modułu MMSystem i należy użyć funkcji WaveOutGetNumDevs
if WaveOutGetNumDevs > 0 then
Label1.Caption := 'Jest karta dźwiękowa!'
else Label1.Caption := 'Brak karty dźwiękowej!';
Do podawania wolnej ilości na dysku służy funkcja DiskFree, a do podawania całego rozmiaru służy DiskSize.
begin
Label1.Caption := Format('Wolne miejsce: %d',[DiskFree(0)]);
Label2.Caption := Format('Całe miejsce: %d', [DiskSize(0)]);
end;
var S : String;
begin
S := 'zdjecie.bmp';
SystemParametersInfo(SPI_SETDESKWALLPAPER,0, PChar(s),
SPIF_UPDATEINIFILE or SPIF_SENDWININICHANGE);
end;
Należy wysłać komunikat wm_SysCommand z parametrem wParam ustawionym na SC_MonitorPower zaś lParam ustawionym na:
0 - aby wyłączyć monitor
1 - aby go włączyć z powrotem
// Wyłączenie monitora:
SendMessage(Application.Handle,wm_SysCommand,SC_MonitorPower,0);
// Włączenie monitora.................
SendMessage(Application.Handle,wm_SysCommand,SC_MonitorPower, 1);
// Uśpienie komputera...............
SendMessage(Application.Handle,wm_SysCommand,SC_SCREENSAVE,-1);
//włączenie blokady......
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, Word(False), nil, 0);
//wyłączenie blokady......
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, Word(True), nil, 0);
funkcja SetScreenResolution bierze pożądaną szerokość i wysokość jako parametry i zwraca
(zmienia) według innej funkcji API Windowsa - ChangeDisplaySettings.
function SetScreenResolution(Width, Height: integer): Longint;
var DeviceMode: TDeviceMode;
begin
with DeviceMode do begin
dmSize := SizeOf(TDeviceMode);
dmPelsWidth := Width;
dmPelsHeight := Height;
dmFields := DM_PELSWIDTH or DM_PELSHEIGHT;
end;
Result := ChangeDisplaySettings(DeviceMode, CDS_UPDATEREGISTRY);
end;
funkcji ChangeDisplaySettings można użyć , by zmienić inne własności takie jak głębia koloru czy
częstotliwość pokazu
Poniższy przykład - button1 zmienia rozdzielczość ekrany na 800x600 ale przed tym zapamiętuje
urozdzielczość dotychczasową. button2 - przywraca dotychczasowe ustawienia
var OldWidth, OldHeight: integer;
procedure TForm1.Button1Click(Sender: TObject);
begin
OldWidth := GetSystemMetrics(SM_CXSCREEN);
OldHeight := GetSystemMetrics(SM_CYSCREEN);
SetScreenResolution(800, 600);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
SetScreenResolution(OldWidth, OldHeight);
end;
Procedure TForm1.Button1Click(Send: TObject);
var loop1,loop2 : integer; startcount, endcount, frequency : TLargeInteger;
Elapsedtime : Extended;
Begin
QueryPerformanceFrequency(Frequency) {odczytaj aktualną częstotliwość zegara}
QueryPerformaceCounter(Startcount); {Start odczytu}
For loop1 := 0 to 99 do
for loop2 := 0 to 99 do
StringGrid1.cells[loop2,loop1] := inttostr((loop1*100)+loop2); {wstaw do celi Stringgrida}
QueryPerformanceCounter(Endcount); {koniec odczytu}
Elapsedtime := (Endcount.Quadpart-Startcount.QuadPart)/Frequency.QuadPart;
{obliczony czas jaki upłynął na wykonanie tej funkcji}
Label1.Caption := 'Wykonanie w czasie : '+FloatTostr(ElapsedTime)+' sekund.';
End;
Można łatwo symulować kliki myszy albo ruchy wg funkcji mouse_event.
Przykład: z chwilą włączenia programu ten pokazuje planszę jak gdyby użytkownik ustawił kursor
myszy na pozycji x,y= 300,400 i dwukrotnie kliknął myszą - tą robotę wykonuje aktywny Timer.
procedure TForm1.FormCreateOrWhatever;
begin
winexec('myexternalapplication.exe',sw_shownormal); // start aplikacji
timer1.interval:=2000; // interwał zegara 2 sek -po tym czasie ruszy
timer1.enabled:=true; // start zegara
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var point:TPoint; // daje aktualną pozycję kursora()
begin
getcursorpos(point); // odczyt aktualnej pozycji
setcursorpos(300,400); // przeniesiena na taką...
mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0); // wciśnięty klawisz myszy
mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0); // +klawisz puszczony + 2-krotny klik
setcursorpos(point.x,point.y); // ustawia kursor na poprzedniej pozycji
timer1.enabled:=false; // stop
end;
Gdy program jest wykonywany -- ruchy myszą są zablokowane!
Podanie na ListBoxa wykazu graficznych urządeń wyjściowych jakie są w komputerze dostępne
procedure TForm1.ButtonClick(Sender: TObject);
var lpDisplayDevice: TDisplayDevice; dwFlags: DWORD; cc: DWORD;
begin
lpDisplayDevice.cb := sizeof(lpDisplayDevice);
dwFlags := 0; cc:= 0;
while EnumDisplayDevices(nil, cc, lpDisplayDevice , dwFlags) do begin
Inc(cc);
aListbox.Items.Add(lpDisplayDevice.DeviceString); {dodawane są informacje z lpDisplayDevice}
end;
end;
Innym sposobem jest odczyt ustawień karty graficznej zapisany w rejestrze podczas instalacji
systemu z następujących kluczy:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Class\Display
%HKLM%\System\CurrentControlSet\Services\Class\Display\0000;
%HKLM%\System\CurrentControlSet\Services\Class\Display\0001;
%HKLM%\System\CurrentControlSet\Services\Class\Display\0002;
{ odczyt rozmiaru czcionki }
function GetMenuFontSize: Integer;
var ncm: TNonClientMetrics; PixelsPerInch: integer;
begin
ncm.cbSize := sizeof(TNonClientMetrics);
SystemParametersInfo( SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS),
@ncm, SPIF_UPDATEINIFILE );
PixelsPerInch := GetDeviceCaps(GetDC(0), LOGPIXELSY);
Result := -MulDiv(ncm.lfMenuFont.lfHeight, 72, PixelsPerInch);
end;
{ Ustawienie rozmiaru czcionki }
procedure SetMenuFontSize(FontSize: Integer);
var ncm: TNonClientMetrics; PixelsPerInch: Integer;
begin
ncm.cbSize := sizeof(TNonClientMetrics);
SystemParametersInfo( SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS),
@ncm, 0 );
PixelsPerInch := GetDeviceCaps(GetDC(0), LOGPIXELSY);
ncm.lfMenuFont.lfHeight := -MulDiv(FontSize, PixelsPerInch, 72);
SystemParametersInfo( SPI_SETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS),
@ncm, SPIF_UPDATEINIFILE );
end;
Procedura EnableTaskbar znajduje okno paska zadań a potem ShowTasBar(false lub
true) ukrywa lub pokazuje go:
procedure EnableTaskBar(Enable : boolean);
var hTaskBarWindow : HWnd;
begin
hTaskBarWindow:=FindWindow('Shell_TrayWnd',nil);
if hTaskBarWindow < > 0 then
EnableWindow(hTaskBarWindow,Enable);
end;
procedure ShowTaskbar(Visible: boolean);
var hTaskBarWindow : HWnd;
begin
hTaskBarWindow:=FindWindow('Shell_TrayWnd',nil);
if hTaskBarWindow < > 0 then
if Visible then
ShowWindow(hTaskBarWindow, SW_SHOW)
else
ShowWindow(hTaskBarWindow, SW_HIDE)
end;
Ten mały fragment kodu pozwala na szybkie tworzenie obrony shareware, która nie wpływa na funkcjonalność programu, ale "prosi", aby zarejestrować program. Program z tym kodem (jak shareware) może być użyty tylko 1 raz; ponowne użycie - po restarcie systemu. Bazuje na obsłudze zdarzenia - w Onformshow:
procedure tform1.formshow(sender: tobject);
var atom: integer; crlf: string;
begin
if globalfindatom('this_is_some_obscuree_text') = 0 then
atom := globaladdatom('this_is_some_obscuree_text') //unikalny string w PC
else begin
crlf := #10 + #13; //zmiana linii i na początek wiersza
showmessage('Ta wersja może być użyta tylko raz '
+ 'w danym seansie Windowsa.' + crlf
+ 'dla kolejnych uruchomień'
+ crlf + 'należy program ZAREJESTROWAĆ !');
close;
end; end;
function driveexists(drive:byte):boolean;
function driveexists(drive:byte):boolean;
var drives: set of 0..25;
begin
integer(drives):=getlogicaldrives; result:=drive in drives
end;
function checkdrivetype(drive: byte): string;
var driveletter: char; drivetype: uint;
begin
driveletter:=chr(drive + $41); drivetype:=getdrivetype(pchar(driveletter + ':'));
case drivetype of
0: result:='?';
1: result:='ścieżka nie istnieje';
drive_removable: result:='removable'; drive_fixed: result:='fixed';
drive_remote: result:='remote'; drive_cdrom: result:='cd_rom';
drive_ramdisk: result:='ramdisk'
else
result:='nieznany' end
end;
var drives: set of 0..25;
begin
integer(drives):=getlogicaldrives; result:=drive in drives
end;
function checkdrivetype(drive: byte): string;
var driveletter: char; drivetype: uint;
begin
driveletter:=chr(drive + $41); drivetype:=getdrivetype(pchar(driveletter + ':'));
case drivetype of
0: result:='?';
1: result:='ścieżka nie istnieje';
drive_removable: result:='removable'; drive_fixed: result:='fixed';
drive_remote: result:='remote'; drive_cdrom: result:='cd_rom';
drive_ramdisk: result:='ramdisk'
else
result:='nieznany' end
end;
unit unit1;
interface
uses windows, messages, sysutils, variants, classes, graphics, controls, forms, dialogs, stdctrls;
type tform1 = class(tform)
button1: tbutton;
button2: tbutton;
procedure button1click(sender: tobject);
procedure button2click(sender: tobject);
procedure formcreate(sender: tobject);
procedure formdestroy(sender: tobject);
private { private declarations }
public { public declarations }
end;
var form1: tform1;
implementation
{$r *.dfm}
type tramparray=array[0..2] of array[byte] of word; //tablica przechowuje gamma kolorów
var origramparray:tramparray; // aktualne wartości gammy
//funkcja zmiany jasności - wbrightness - tym jaśniejszy
function setbrightness(wbrightness:word):boolean;
var ramparray:tramparray; i, value:integer; dc:hdc;
begin
for i:=0 to maxbyte do
begin
value := i * (wbrightness + 128); if (value > maxword) then value := maxword;
ramparray[0][i] := value; ramparray[1][i] := value; ramparray[2][i] := value;
end;
dc:=getdc(0); try result:= setdevicegammaramp(dc,ramparray)
finally releasedc(0,dc)
end end;
// zachowuje aktualne wartości gamma
procedure tform1.formcreate(sender: tobject);
var dc:hdc;
begin
dc:=getdc(0);
try getdevicegammaramp(dc,origramparray)
finally releasedc(0,dc)
end end;
// zmieniamy jasność
procedure tform1.button1click(sender: tobject);
begin
setbrightness(64)
end;
// przywracamy poprzednią gamme kolorów
procedure tform1.button2click(sender: tobject);
var dc:hdc;
begin
dc:=getdc(0);
try setdevicegammaramp(dc,origramparray)
finally releasedc(0,dc)
end end;
procedure tform1.formdestroy(sender: tobject);
begin
button2click(button2)
end;
end.
1.
Function GetVolumeInfoFVS(Const Dir:string;
Var FileSystemName,VolumeName:string;Var Serial:longint):boolean;
{pobieranie informacji o dysku
Dir - katalog lub wybrana partycja dysku
FileSystemName - nazwa systemu plików
VolumeName - etykieta dysku
Serial - numer seryjny dysku - w przypadku błędu funkcja zwraca False}
var root:pchar; res:longbool;
VolumeNameBuffer,FileSystemNameBuffer:pchar;
VolumeNameSize,FileSystemNameSize:DWord;
VolumeSerialNumber,MaximumComponentLength,FileSystemFlags:DWORD;
s:string; n:integer;
Begin
n:=pos(':',Dir); If n>0 Then s:=copy(Dir,1,n+1) Else s:=s+':';
If s[length(s)]=':' Then s:=s+'\'; root:=pchar(s);
getMem(VolumeNameBuffer,256); getMem(FileSystemNameBuffer,256);
VolumeNameSize:=255; FileSystemNameSize:=255;
res:=GetVolumeInformation(Root,VolumeNameBuffer,VolumeNameSize
,@VolumeSerialNumber, MaximumComponentLength, FileSystemFlags
,FileSystemNameBuffer,FileSystemNameSize);
Result:=res;
VolumeName:=VolumeNameBuffer; FileSystemName:=FileSystemNameBuffer;
Serial:=VolumeSerialNumber;
freeMem(VolumeNameBuffer,256); freeMem(FileSystemNameBuffer,256);
End;
2.
Function GetHDSerNo: shortstring; export;
var VolumeName, FileSystemName : array [0..MAX_PATH-1] of Char;
VolumeSerialNo : Cardinal; MaxComponentLength, FileSystemFlags : DWORD;
Begin
Try GetVolumeInformation('C:\',VolumeName,MAX_PATH,@VolumeSerialNo,
MaxComponentLength,FileSystemFlags, FileSystemName,MAX_PATH);
Result:=IntToHex(HiWord(VolumeSerialNo),4)+ '-'+IntToHex(LoWord(VolumeSerialNo),4);
Except;
End; End
3.
Procedure TForm1.Button1Click(SEnder: TObject);
var VolumeName,FileSystemName : array [0..MAX_PATH-1] of Char;
VolumeSerialNo : DWord;MaxComponentLength, FileSystemFlags : Cardinal;
Begin
GetVolumeInformation('C:\',VolumeName,MAX_PATH,@VolumeSerialNo,
MaxComponentLength,FileSystemFlags,FileSystemName,MAX_PATH);
Memo1.Lines.Add('VName = '+VolumeName);
Memo1.Lines.Add('SerialNo = $'+IntToHex(VolumeSerialNo,8));
Memo1.Lines.Add('CompLen = '+IntToStr(MaxComponentLength));
Memo1.Lines.Add('Flags = $'+IntToHex(FileSystemFlags,4));
Memo1.Lines.Add('FSName = '+FileSystemName);
End;
type {...}
private
procedure wmdisplaychange(var msg: tmessage);
message wm_displaychange;
public {...}
end; end;
var form1: tform1;
implementation
{$r *.dfm}
procedure tform1.wmdisplaychange(var msg: tmessage);
begin
showmessage('wyswietlanie ekranu zmienione!');
inherited;
end;
Poniższy przykład pokazuje, jak ustalić, czy naciśnięty klawisz Shift podczas wybierania wiersza menu.Przykład zawiera także klawisze stan funkcji Alt, Ctrl.
function CtrlDown : Boolean;
var State : TKeyboardState;
begin
GetKeyboardState(State); Result := ((State[vk_Control] And 128) < > 0);
end;
function ShiftDown : Boolean;
var State : TKeyboardState;
begin
GetKeyboardState(State); Result := ((State[vk_Shift] and 128) < > 0);
end;
function AltDown : Boolean;
var State : TKeyboardState;
begin
GetKeyboardState(State); Result := ((State[vk_Menu] and 128) < > 0);
end;
procedure TForm1.MenuItem12Click(Sender: TObject);
begin
if ShiftDown then Form1.Caption := 'Shift' else Form1.Caption := '';
end;
W NT/2000/XP nie można odczytać wartości bezpośrednio z biosu, ale nic nie stoi na przeszkodzie, aby wziąć pod uwagę odpowiednie wartości z rejestru.
procedure tbiosinfo.getreginfowinnt;
var registryv : tregistry; regpath : string; sl : tstrings;
begin
params.clear;
regpath := '\hardware\description\system';
registryv:=tregistry.create;
registryv.rootkey:=hkey_local_machine;
sl := nil;
try
registryv.openkey(regpath,false);
showmessage('bios date: '+registryv.readstring('systembiosdate'));
sl := readmultirowkey(registryv,'systembiosversion');
showmessage('bios version: '+sl.text);
except
end; registryv.free; if assigned(sl) then sl.free;
end;
/ / Poniższa metoda pobiera wiele wartości z rejestru
/ / i zamienia je na TStringList
function readmultirowkey(reg: tregistry; key: string): tstrings;
const bufsize = 100;
var i: integer; s1: string; sl: tstringlist;
bin: array[1..bufsize] of char;
begin
try result := nil; sl := nil; sl := tstringlist.create;
if not assigned(reg) then
raise exception.create('tregistry object not assigned.');
fillchar(bin,bufsize,#0); reg.readbinarydata(key,bin,bufsize);
i := 1; s1 := '';
while i < bufsize do begin
if ord(bin[i]) >= 32 then
s1 := s1 + bin[i]
else begin
if length(s1) > 0 then begin
sl.add(s1); s1 := ''; end; end; inc(i); end; result := sl;
except
sl.free; raise; end;
end;
W NT/2000/XP nie być w stanie odczytać wartości bezpośrednio z biosu, ale nic nie stoi na przeszkodzie, aby wziąć pod uwagę odpowiednie wartości z rejestru.
procedure tbiosinfo.getreginfowinnt; //odczyt wersji biosu
var registryv: tregistry; regpath: string; sl: tstrings;
begin
params.clear; regpath := 'hardwaredescriptionsystem';
registryv := tregistry.create; registryv.rootkey := hkey_local_machine;
sl := nil;
try
registryv.openkey(regpath, false);
showmessage('bios date: ' + registryv.readstring('systembiosdate'));
sl := readmultirowkey(registryv, 'systembiosversion');
showmessage('bios version: ' + sl.text);
except
end; registryv.free; if assigned(sl) then sl.free;
end;
/ / Poniższa metoda pobiera wielu wartości z rejestru
/ / I zamienia je na TStringList
function readmultirowkey(reg: tregistry; key: string): tstrings;
const bufsize = 100;
var i: integer; s1: string; sl: tstringlist; bin: array[1..bufsize] of char;
begin
try result := nil; sl := nil; sl := tstringlist.create;
if not assigned(reg) then
raise exception.create('tregistry object not assigned.');
fillchar(bin, bufsize, #0);
reg.readbinarydata(key, bin, bufsize); i := 1; s1 := '';
while i < bufsize do
begin
if ord(bin[i]) >= 32 then s1 := s1 + bin[i]
else begin
if length(s1) > 0 then
begin
sl.add(s1); s1 := ''; end; end; inc(i); end; result := sl;
except
sl.free; raise; end;
end;
Rozwiązać problem za pomocą winapi. Jeśli jesteś zainteresowany, tutaj jest mój kod:
unit unit1;
interface
uses windows, messages, forms;
type tform1 = class(tform)
procedure formcreate(sender: tobject);
private
procedure wm_hotkeyhandler (var message: tmessage);
message wm_hotkey;
public{ public declarations }
end;
var form1: tform1; hk_mute,hk_volumeup,hk_volumedown,hk_next,
hk_prev, hk_stop, hk_playpause:integer;
implementation
{$r *.dfm}
procedure tform1.wm_hotkeyhandler (var message: tmessage);
var idhotkey: integer; fumodifiers: word; hotkey: word;
begin
idhotkey:= message.wparam; fumodifiers:= loword(message.lparam);
hotkey:= hiword(message.lparam);
case hotkey of
173: caption:='mute'; 174: caption:='volumeup'; 175: caption:='volumedown';
176: caption:='nexttrack'; 177: caption:='prevtrack'; 178: caption:='stop';
179: caption:='play/pause'; end; inherited;
end;
procedure tform1.formcreate(sender: tobject);
begin
hk_mute:=globaladdatom('mute'); registerhotkey(handle,hk_mute,0,173);
hk_volumeup:=globaladdatom('volumeup'); registerhotkey(handle,hk_volumeup,0,174);
hk_volumedown:=globaladdatom('volumedown');
registerhotkey(handle,hk_volumedown,0,175);
hk_next:=globaladdatom('nexttrack'); registerhotkey(handle,hk_next,0,176);
hk_prev:=globaladdatom('prevtrack'); registerhotkey(handle,hk_prev,0,177);
hk_stop:=globaladdatom('stop'); registerhotkey(handle,hk_stop,0,178);
hk_playpause:=globaladdatom('play/pause');
registerhotkey(handle,hk_playpause,0,179);
end;
end.
Te przyciski nie przechwytują jeżeli są uruchomione inne aplikacje, które używają tych przycisków, np, Winamp.
procedure tform1.formcreate(sender: tobject);
var st : string;
begin
st := 'c:\Obrazek.bmp';
systemparametersinfo(spi_setdeskwallpaper,uint(st), nil, spif_sendchange);
end;