Как изменить оконную процедуру для TForm?
Переопределите в подклассе TForm оконную процедуру WinProc класса. В примере оконная процедура переопределяется для того чтобы реагировать на сообщение WM_CANCELMODE, показывающее, что выполняется messagebox или какой-либо еще диалог.
type
TForm1 = class(TForm)
Button1: TButton;
procedure WndProc(var Message: TMessage); override;
procedure Button1Click(Sender: TObject);
private
{Private declarations}
public
{Public declarations}
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.WndProc(var Message: TMessage);
begin
if Message.Msg = WM_CANCELMODE then
begin
Form1.Caption := 'A dialog or message box has popped up';
end
else
inherited // <- остальное сделает родительская процедура
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage('Test Message');
end;
Как изменить порт для принтера?
Как изменить порт для принтера?
uses
WinSpool;
{ Function SetPrinterToPort
Parameters :
hPrinter: handle of printer to change, obtained from OpenPrinter
port: port name to use, e.g. LPT1:, COM1:, FILE:
Returns:
The name of the previous port the printer was attached to.
Description:
Changes the port a printer is attached to using Win32 API functions.
The changes made are NOT local to this process, they will affect all
other processes that try to use this printer! It is recommended to set the
port back to the old port returned by this function after
the end of the print job.
Error Conditions:
Will raise EWin32Error exceptions if SetPrinter or GetPrinter fail.
Created:
21.10.99 by P. Below}
function SetPrinterToPort(hPrinter: THandle; const port: string): string;
var
pInfo: PPrinterInfo2;
bytesNeeded: DWORD;
begin
{Figure out how much memory we need for the data buffer. Note that GetPrinter is
supposed to fail with a specific error code here. The amount of memory will
be larger than Sizeof(TPrinterInfo2) since variable amounts of data are appended
to the record}
SetLastError(NO_ERROR);
GetPrinter(hPrinter, 2, nil, 0, @bytesNeeded);
if GetLastError <> ERROR_INSUFFICIENT_BUFFER then
RaiseLastWin32Error;
pInfo := AllocMem(bytesNeeded);
try
if not GetPrinter(hPrinter, 2, pInfo, bytesNeeded, @bytesNeeded) then
RaiseLastWin32Error;
with pInfo^ do
begin
Result := pPortname;
pPortname := @port[1];
end;
if not SetPrinter(hPrinter, 2, pInfo, 0) then
RaiseLastWin32Error;
finally
FreeMem(pInfo);
end;
end;
function GetCurrentPrinterHandle: THandle;
var
Device, Driver, Port: array[0..255] of char;
hDeviceMode: THandle;
begin
Printer.GetPrinter(Device, Driver, Port, hDeviceMode);
if not OpenPrinter(@Device, Result, nil) then
RaiseLastWin32Error;
end;
Взято с
Delphi Knowledge BaseКак изменить размеры полигона?
Как изменить размеры полигона?
{... }
type
TPolygon = array of TPoint;
procedure ZoomPolygon(var Polygon: TPolygon; const Center: TPoint; const Scale: Double);
var
I: Integer;
begin
for I := 0 to High(Polygon) do
begin
Polygon[I].X := Round(Scale * (Polygon[I].X - Center.X) + Center.X);
Polygon[I].Y := Round(Scale * (Polygon[I].Y - Center.Y) + Center.Y);
end;
end;
Взято с
Delphi Knowledge BaseКак изменить шрифт hint?
Как изменить шрифт hint?
{
When the application displays a Help Hint,
it creates an instance of HintWindowClass to represent
the window used for displaying the hint.
Applications can customize this window by creating a
descendant of THintWindow and assigning it to the
HintWindowClass variable at application startup.
}
type
TMyHintWindow = class(THintWindow)
constructor Create(AOwner: TComponent); override;
end;
implementation
{....}
constructor TMyHintWindow.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
with Canvas.Font do
begin
Name := 'Arial';
Size := Size + 5;
Style := [fsBold];
end;
end;
procedure TForm2.FormCreate(Sender: TObject);
begin
HintWindowClass := TMyHintWindow;
Application.ShowHint := False;
Application.ShowHint := True;
end;
Взято с сайта
Как изменить шрифт и выравнивание в заголовке формы?
Как изменить шрифт и выравнивание в заголовке формы?
Note: The formDeactivate never gets called so when the form isn't active, sometimes the FormPaint isn't called. If anything causes the form to be repainted while in inactive, it draws correctly.
unitUnit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
type
TForm1 = class(TForm)
procedure FormPaint(Sender: TObject);
procedure FormResize(Sender: TObject);
procedure FormDeactivate(Sender: TObject);
procedure FormActivate(Sender: TObject);
private
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.FormPaint(Sender: TObject);
var
LabelHeight, LabelWidth, LabelTop: Integer;
caption_height, border3d_y, button_width, border_thickness: Integer;
MyCanvas: TCanvas;
CaptionBarRect: TRect;
begin
CaptionBarRect := Rect(0, 0, 0, 0);
MyCanvas := TCanvas.Create;
MyCanvas.Handle := GetWindowDC(Form1.Handle);
border3d_y := GetSystemMetrics(SM_CYEDGE);
button_width := GetSystemMetrics(SM_CXSIZE);
border_thickness := GetSystemMetrics(SM_CYSIZEFRAME);
caption_height := GetSystemMetrics(SM_CYCAPTION);
LabelWidth := Form1.Canvas.TextWidth(Form1.Caption);
LabelHeight := Form1.Canvas.TextHeight(Form1.Caption);
LabelTop := LabelHeight - (caption_height div 2);
CaptionBarRect.Left := border_thickness + border3d_y + button_width;
CaptionBarRect.Right := Form1.Width - (border_thickness + border3d_y)
- (button_width * 4);
CaptionBarRect.Top := border_thickness + border3d_y;
CaptionBarRect.Bottom := caption_height;
if Form1.Active then
MyCanvas.Brush.Color := clActiveCaption
else
MyCanvas.Brush.Color := clInActiveCaption;
MyCanvas.Brush.Style := bsSolid;
MyCanvas.FillRect(CaptionBarRect);
MyCanvas.Brush.Style := bsClear;
MyCanvas.Font.Color := clCaptionText;
MyCanvas.Font.Name := 'MS Sans Serif';
MyCanvas.Font.Style := MyCanvas.Font.Style + [fsBold];
DrawText(MyCanvas.Handle, PChar(' ' + Form1.Caption), Length(Form1.Caption) + 1,
CaptionBarRect, DT_CENTER or DT_SINGLELINE or DT_VCENTER);
MyCanvas.Free;
end;
procedure TForm1.FormResize(Sender: TObject);
begin
Form1.Paint;
end;
procedure TForm1.FormDeactivate(Sender: TObject);
begin
Form1.Paint;
end;
procedure TForm1.FormActivate(Sender: TObject);
begin
Form1.Paint;
end;
end.
{ ... }
type
TForm1 = class(TForm)
private
procedure WMNCPaint(var Msg: TWMNCPaint); message WM_NCPAINT;
public
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.WMNCPaint(var Msg: TWMNCPaint);
var
ACanvas: TCanvas;
begin
inherited;
ACanvas := TCanvas.Create;
try
ACanvas.Handle := GetWindowDC(Form1.Handle);
with ACanvas do
begin
Brush.Color := clActiveCaption;
Font.Name := 'Tahoma';
Font.Size := 8;
Font.Color := clred;
Font.Style := [fsItalic, fsBold];
TextOut(GetSystemMetrics(SM_CYMENU) + GetSystemMetrics(SM_CXBORDER),
Round((GetSystemMetrics(SM_CYCAPTION) - Abs(Font.Height)) / 2) + 1,
' Some Text');
end;
finally
ReleaseDC(Form1.Handle, ACanvas.Handle);
ACanvas.Free;
end;
end;
Взято с
Delphi Knowledge BaseКак изменить шрифт определённой строки в DBGrid?
Как изменить шрифт определённой строки в DBGrid?
Для этого надо воспользоваться событием OnDrawDataCell в dbgrid.
procedure TForm1.DBGrid1DrawDataCell(Sender: TObject; const Rect: TRect;
Field: TField; State: TGridDrawState);
begin
// If the record's CustNo is 4711 draw the entire row with a
// line through it. (set the font style to strike out)
if (Sender as TDBGrid).DataSource.DataSet.FieldByName('CustNo').AsString =
'4711' then
with (Sender as TDBGrid).Canvas do
begin
FillRect(Rect);
// Set the font style to StrikeOut
Font.Style := Font.Style + [fsStrikeOut];
// Draw the cell right aligned for floats + offset
if (Field.DataType = ftFloat) then
TextOut(Rect.Right - TextWidth(Field.AsString) - 3,
Rect.Top + 3, Field.AsString)
// Otherwise draw the cell left aligned + offset
else
TextOut(Rect.Left + 2, Rect.Top + 3, Field.AsString);
end;
end;
Замечание: Вышеприведённый код использует таблицу "CUSTOMER.DB", TDBGrid, TDataSource
и TTable
Взято с Исходников.ru
Как изменить системное время?
Как изменить системное время?
Функция SetSystemTime.
Обрати внимание на привилегии.
Автор ответа: podval
Взято с Vingrad.ru
1) Вариант №1
//**********************************************************
// Функция (раздел Public) SetPCSystemTime изменяет системную дату и время.
// Параметр(ы) : tDati Новая дата и время
// Возвращаемые значения: True - успешное завершение
// False - метод несработал
//************************************************************
function SetPCSystemTime(tDati: TDateTime): Boolean;
var
tSetDati: TDateTime;
vDatiBias: Variant;
tTZI: TTimeZoneInformation;
tST: TSystemTime;
begin
GetTimeZoneInformation(tTZI);
vDatiBias := tTZI.Bias / 1440;
tSetDati := tDati + vDatiBias;
with tST do
begin
wYear := StrToInt(FormatDateTime('yyyy', tSetDati));
wMonth := StrToInt(FormatDateTime('mm', tSetDati));
wDay := StrToInt(FormatDateTime('dd', tSetDati));
wHour := StrToInt(FormatDateTime('hh', tSetDati));
wMinute := StrToInt(FormatDateTime('nn', tSetDati));
wSecond := StrToInt(FormatDateTime('ss', tSetDati));
wMilliseconds := 0;
end;
SetPCSystemTime := SetSystemTime(tST);
end;
2) Вариант №2
***************************************************
Для изменения системного времени используется сложный спобой (через строки).
DateTimeToSystemTime(tSetDati,Tst); - работает быстрее и код короче
3) третий способ:
/////////////////////////////////////////////////////////////
Procedure settime(hour, min, sec, hundreths : byte); assembler;
asm
mov ch, hour
mov cl, min
mov dh, sec
mov dl, hundreths
mov ah, $2d
int $21
end;
////////////////////////////////////////////////////////////////////////
Procedure setdate(Year : word; Month, Day : byte); assembler;
asm
mov cx, year
mov dh, month
mov dl, day
mov ah, $2b
int $21
end;
Автор ответа: Pegas
Взято с Vingrad.ru
Следующие несколько строк кода позволяют установить системную дату и время без использования панели управления. Дата и время устанавливаются двумя раздельными компонентами TDateTimePicker. Дата и время декодируются и передаются в API функцию.
Из значения часа вычитается 2 для установки правильного времени. (Примечание Vit: вычитается не 2 часа а разница с Гринвичем)
procedure TfmTime.btnTimeClick(Sender: TObject);
var vsys : _SYSTEMTIME;
vYear, vMonth, vDay, vHour, vMin, vSec, vMm : Word;
begin
DecodeDate( Trunc(dtpDate.Date), vYear, vMonth, vDay );
DecodeTime( dtpTime.Time, vHour, vMin, vSec, vMm );
vMm := 0;
vsys.wYear := vYear;
vsys.wMonth := vMonth;
vsys.wDay := vDay;
vsys.wHour := ( vHour - 2 );
vsys.wMinute := vMin;
vsys.wSecond := vSec;
vsys.wMilliseconds := vMm;
vsys.wDayOfWeek := DayOfWeek( Trunc(dtpDate.Date) );
SetSystemTime( vsys );
end;
Взято с Исходников.ru
Как изменить стандартный цвет ProgressBar?
Как изменить стандартный цвет ProgressBar?
Самый простой способ, это изменить цветовую схему в свойствах экрана...
А вот при помощи следующей команды можно разукрасить ProgressBar не изменяя системных настроек:
PostMessage(ProgressBar1.Handle, $0409, 0, clGreen);
Вуаля! Теперь Progress Bar зелёный. Это всего лишь простой пример чёрной магии ;)
Взято с Исходников.ru
Как изменить уровень громкости микрофона?
Как изменить уровень громкости микрофона?
uses
MMSystem;
// Setzt die Lautstarke fur das Mikrofon
// Set the volume for the microphone
function SetMicrophoneVolume(bValue: Word): Boolean;
var {0..65535}
hMix: HMIXER;
mxlc: MIXERLINECONTROLS;
mxcd: TMIXERCONTROLDETAILS;
vol: TMIXERCONTROLDETAILS_UNSIGNED;
mxc: MIXERCONTROL;
mxl: TMixerLine;
intRet: Integer;
nMixerDevs: Integer;
begin
// Check if Mixer is available
// Uberprufen, ob ein Mixer vorhanden
nMixerDevs := mixerGetNumDevs();
if (nMixerDevs < 1) then
begin
Exit;
end;
// open the mixer
intRet := mixerOpen(@hMix, 0, 0, 0, 0);
if intRet = MMSYSERR_NOERROR then
begin
mxl.dwComponentType := MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE;
mxl.cbStruct := SizeOf(mxl);
// get line info
intRet := mixerGetLineInfo(hMix, @mxl, MIXER_GETLINEINFOF_COMPONENTTYPE);
if intRet = MMSYSERR_NOERROR then
begin
ZeroMemory(@mxlc, SizeOf(mxlc));
mxlc.cbStruct := SizeOf(mxlc);
mxlc.dwLineID := mxl.dwLineID;
mxlc.dwControlType := MIXERCONTROL_CONTROLTYPE_VOLUME;
mxlc.cControls := 1;
mxlc.cbmxctrl := SizeOf(mxc);
mxlc.pamxctrl := @mxc;
intRet := mixerGetLineControls(hMix, @mxlc, MIXER_GETLINECONTROLSF_ONEBYTYPE);
if intRet = MMSYSERR_NOERROR then
begin
{
// Microphone Name
Label1.Caption := mxlc.pamxctrl.szName;
// Min/Max Volume
Label2.Caption := IntToStr(mxc.Bounds.dwMinimum) + '->' + IntToStr(mxc.Bounds.dwMaximum);
}
ZeroMemory(@mxcd, SizeOf(mxcd));
mxcd.dwControlID := mxc.dwControlID;
mxcd.cbStruct := SizeOf(mxcd);
mxcd.cMultipleItems := 0;
mxcd.cbDetails := SizeOf(Vol);
mxcd.paDetails := @vol;
mxcd.cChannels := 1;
// vol.dwValue := mxlc.pamxctrl.Bounds.lMinimum; Set min. Volume / Minimum setzen
// vol.dwValue := mxlc.pamxctrl.Bounds.lMaximum; Set max. Volume / Maximum setzen
vol.dwValue := bValue;
intRet := mixerSetControlDetails(hMix, @mxcd,
MIXER_SETCONTROLDETAILSF_VALUE);
if intRet <> MMSYSERR_NOERROR then
ShowMessage('SetControlDetails Error');
end
else
ShowMessage('GetLineInfo Error');
end;
intRet := mixerClose(hMix);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
SetMicrophoneVolume(30000);
end;
{********************************************************}
// Enable/disable "Mute Microphone Volume"
// Ton fur Mikrofon ein/ausschalten
function SetMicrophoneVolumeMute(bMute: Boolean): Boolean;
var
hMix: HMIXER;
mxlc: MIXERLINECONTROLS;
mxcd: TMIXERCONTROLDETAILS;
vol: TMIXERCONTROLDETAILS_UNSIGNED;
mxc: MIXERCONTROL;
mxl: TMixerLine;
intRet: Integer;
nMixerDevs: Integer;
mcdMute: MIXERCONTROLDETAILS_BOOLEAN;
begin
// Check if Mixer is available
// Uberprufen, ob ein Mixer vorhanden ist
nMixerDevs := mixerGetNumDevs();
if (nMixerDevs < 1) then
begin
Exit;
end;
// open the mixer
// Mixer offnen
intRet := mixerOpen(@hMix, 0, 0, 0, 0);
if intRet = MMSYSERR_NOERROR then
begin
mxl.dwComponentType := MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE;
mxl.cbStruct := SizeOf(mxl);
// mixerline info
intRet := mixerGetLineInfo(hMix, @mxl, MIXER_GETLINEINFOF_COMPONENTTYPE);
if intRet = MMSYSERR_NOERROR then
begin
ZeroMemory(@mxlc, SizeOf(mxlc));
mxlc.cbStruct := SizeOf(mxlc);
mxlc.dwLineID := mxl.dwLineID;
mxlc.dwControlType := MIXERCONTROL_CONTROLTYPE_MUTE;
mxlc.cControls := 1;
mxlc.cbmxctrl := SizeOf(mxc);
mxlc.pamxctrl := @mxc;
// Get the mute control
// Mute control ermitteln
intRet := mixerGetLineControls(hMix, @mxlc, MIXER_GETLINECONTROLSF_ONEBYTYPE);
if intRet = MMSYSERR_NOERROR then
begin
ZeroMemory(@mxcd, SizeOf(mxcd));
mxcd.cbStruct := SizeOf(TMIXERCONTROLDETAILS);
mxcd.dwControlID := mxc.dwControlID;
mxcd.cChannels := 1;
mxcd.cbDetails := SizeOf(MIXERCONTROLDETAILS_BOOLEAN);
mxcd.paDetails := @mcdMute;
mcdMute.fValue := Ord(bMute);
// set, unset mute
// Stumsschalten ein/aus
intRet := mixerSetControlDetails(hMix, @mxcd,
MIXER_SETCONTROLDETAILSF_VALUE);
{
mixerGetControlDetails(hMix, @mxcd,
MIXER_GETCONTROLDETAILSF_VALUE);
Result := Boolean(mcdMute.fValue);
}
Result := intRet = MMSYSERR_NOERROR;
if intRet <> MMSYSERR_NOERROR then
ShowMessage('SetControlDetails Error');
end
else
ShowMessage('GetLineInfo Error');
end;
intRet := mixerClose(hMix);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
SetMicrophoneVolumeMute(False);
end;
{********************************************************}
// Enable/disable "Mute" for several mixer line sources.
uses
MMSystem;
type
TMixerLineSourceType = (lsDigital, lsLine, lsMicrophone, lsCompactDisk, lsTelephone,
lsWaveOut, lsAuxiliary, lsAnalog, lsLast);
function SetMixerLineSourceMute(AMixerLineSourceType: TMixerLineSourceType; bMute: Boolean): Boolean;
var
hMix: HMIXER;
mxlc: MIXERLINECONTROLS;
mxcd: TMIXERCONTROLDETAILS;
vol: TMIXERCONTROLDETAILS_UNSIGNED;
mxc: MIXERCONTROL;
mxl: TMixerLine;
intRet: Integer;
nMixerDevs: Integer;
mcdMute: MIXERCONTROLDETAILS_BOOLEAN;
begin
Result := False;
// Check if Mixer is available
// Uberprufen, ob ein Mixer vorhanden ist
nMixerDevs := mixerGetNumDevs();
if (nMixerDevs < 1) then
begin
Exit;
end;
// open the mixer
// Mixer offnen
intRet := mixerOpen(@hMix, 0, 0, 0, 0);
if intRet = MMSYSERR_NOERROR then
begin
ZeroMemory(@mxl, SizeOf(mxl));
case AMixerLineSourceType of
lsDigital: mxl.dwComponentType :=MIXERLINE_COMPONENTTYPE_SRC_DIGITAL;
lsLine: mxl.dwComponentType := MIXERLINE_COMPONENTTYPE_SRC_LINE;
lsMicrophone: mxl.dwComponentType :=MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE;
lsCompactDisk: mxl.dwComponentType :=MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC;
lsTelephone: mxl.dwComponentType :=MIXERLINE_COMPONENTTYPE_SRC_TELEPHONE;
lsWaveOut: mxl.dwComponentType :=MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT;
lsAuxiliary: mxl.dwComponentType :=MIXERLINE_COMPONENTTYPE_SRC_AUXILIARY;
lsAnalog : mxl.dwComponentType :=MIXERLINE_COMPONENTTYPE_SRC_ANALOG;
lsLast: mxl.dwComponentType :=MIXERLINE_COMPONENTTYPE_SRC_LAST;
end;
// mixerline info
mxl.cbStruct := SizeOf(mxl);
intRet := mixerGetLineInfo(hMix, @mxl, MIXER_GETLINEINFOF_COMPONENTTYPE);
if intRet = MMSYSERR_NOERROR then
begin
ZeroMemory(@mxlc, SizeOf(mxlc));
mxlc.cbStruct := SizeOf(mxlc);
mxlc.dwLineID := mxl.dwLineID;
mxlc.dwControlType := MIXERCONTROL_CONTROLTYPE_MUTE;
mxlc.cControls := 1;
mxlc.cbmxctrl := SizeOf(mxc);
mxlc.pamxctrl := @mxc;
// Get the mute control
// Mute control ermitteln
intRet := mixerGetLineControls(hMix, @mxlc, MIXER_GETLINECONTROLSF_ONEBYTYPE);
if intRet = MMSYSERR_NOERROR then
begin
ZeroMemory(@mxcd, SizeOf(mxcd));
mxcd.cbStruct := SizeOf(TMIXERCONTROLDETAILS);
mxcd.dwControlID := mxc.dwControlID;
mxcd.cChannels := 1;
mxcd.cbDetails := SizeOf(MIXERCONTROLDETAILS_BOOLEAN);
mxcd.paDetails := @mcdMute;
mcdMute.fValue := Ord(bMute);
// set, unset mute
// Stumsschalten ein/aus
intRet := mixerSetControlDetails(hMix, @mxcd, MIXER_SETCONTROLDETAILSF_VALUE);
{
mixerGetControlDetails(hMix, @mxcd, IXER_GETCONTROLDETAILSF_VALUE);
Result := Boolean(mcdMute.fValue);
}
Result := intRet = MMSYSERR_NOERROR;
if intRet <> MMSYSERR_NOERROR then
ShowMessage('SetControlDetails Error');
end
else
ShowMessage('GetLineInfo Error');
end;
intRet := mixerClose(hMix);
end;
end;
// Example Call; Beispielaufruf:
procedure TForm1.Button1Click(Sender: TObject);
begin
// Ton ausschalten
SetMixerLineSourceMute(lsLine, True);
end;
Взято с сайта
Как изменить заголовок чужого окна?
Как изменить заголовок чужого окна?
SetWindowText(FindWindow(nil,'Текущий заголовок'), 'Желаемый');
Взято с Исходников.ru
Автор trainer
Как изменить значение свойства компонента по имени?
Как изменить значение свойства компонента по имени?
functionGetProperty(AControl: TPersistent; AProperty: String): PPropInfo;
var
i: Integer;
props: PPropList;
typeData: PTypeData;
begin
Result := nil;
if (AControl = nil) or (AControl.ClassInfo = nil) then
Exit;
typeData := GetTypeData(AControl.ClassInfo);
if (typeData = nil) or (typeData^.PropCount = 0) then
Exit;
GetMem(props, typeData^.PropCount * SizeOf(Pointer));
try
GetPropInfos(AControl.ClassInfo, props);
for i := 0 to typeData^.PropCount - 1 do
begin
with Props^[i]^ do
if (Name = AProperty) then
result := Props^[i];
end;
finally
FreeMem(props);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
propInfo: PPropInfo;
begin
PropInfo := GetProperty(Button1.Font, 'Name');
if PropInfo <> nil then
SetStrProp(Button1.Font, PropInfo, 'Arial');
end;
Взято из
You can use RTTI to do this. Here is how to change a particular component:
procedure TForm1.BtnClick(Sender: TObject);
var
p: PPropInfo;
f: TFont;
begin
f := TFont.Create;
{Setup the font properties}
f.Name := 'Arial';
p := GetPropInfo(Sender.ClassInfo, 'Font');
if Assigned(p) then
SetOrdProp(Sender, p, Integer(f));
f.Free;
end;
To get at all the forms loop through the Screen global variable. For each form loop through its Components list calling the above procedure (or something close). If you only create your components at design time that is it. If you create some at runtime and the owner is not the form, then for each component loop through its Components list recursively to get at all the owned components.
Tip by Jeff Overcash
Взято из
I am building a routine that checks our forms for validity before deploying them. I would like to use some kind of structure that tests if a component type has access to a certain property, something like: " if (self.Controls[b] has Tag) then ...". Can anyone offer suggestions?
Here's an example of setting a string property for a component if it exists and another for an integer property:
procedureSetStringPropertyIfExists(AComp: TComponent; APropName: String;
AValue: String);
var
PropInfo: PPropInfo;
TK: TTypeKind;
begin
PropInfo := GetPropInfo(AComp.ClassInfo, APropName);
if PropInfo <> nil then
begin
TK := PropInfo^.PropType^.Kind;
if (TK = tkString) or (TK = tkLString) or (TK = tkWString) then
SetStrProp(AComp, PropInfo, AValue);
end;
end;
procedure SetIntegerPropertyIfExists(AComp: TComponent; APropName: String;
AValue: Integer);
var
PropInfo: PPropInfo;
begin
PropInfo := GetPropInfo(AComp.ClassInfo, APropName);
if PropInfo <> nil then
begin
if PropInfo^.PropType^.Kind = tkInteger then
SetOrdProp(AComp, PropInfo, AValue);
end;
end;
Tip by Xavier Pacheco
Взято из
Как извлечь иконку из EXE или DLL?
Как извлечь иконку из EXE или DLL?
Такой вот совет пришел ко мне с рассылкой "Ежедневная рассылка сайта Мастера DELPHI", думаю многим будет интересно.
Решить эту задачу нам поможет функция function ExtractIcon(hInstance, filename, iconindex):integer
где hinstance - глобальная переменная приложения, ее изменять не надо. Тип integer.
filename - имя программы или DLL из которой надо извлекать иконки. Тип pchar.
iconindex - порядковый номер иконки в файле (начинается с 0). В одном файле может находится несколько иконок. Тип integer.
Функция находится в модуле ShellApi, так что не забудьте подключить его в uses. Если эта функция возвратит ноль, значит иконок в файле нет.
Данная функция возвращает handle иконки, поэтому применять ее нужно так:
Image1.Picture.Icon.Handle:=ExtractIcon(hInstance, pchar(paramstr(0)), 0);
данное объявление нарисует в Image'e картинку вашего приложения.
Автор: Михаил Христосенко
Взято с Vingrad.ru
Как я могу работать с IB с клиентского компьютера?
Как я могу работать с IB с клиентского компьютера?
Можно использовать IB API (либо наборы компонт FreeIBComponents, IBObjects, IBX или FIBPlus, работающие напрямую с IB API), BDE+SQL Links, либо ODBC-драйвер.
Схема обмена данными между этими компонентами следующая
GDS32.DLL->IB прямое обращение к IB API
ODBC->GDS32.DLL-> IB работа через ODBC
BDE->SQL Link->GDS32.DLL->IB работа через BDE
BDE->ODBC->GDS32.DLL->IB работа через BDE, ODBC вместо SQL Link.
Практически во всех случаях вам не требуется производить какие-либо специфические настройки.
Borland Interbase / Firebird FAQ
Borland Interbase / Firebird Q&A, версия 2.02 от 31 мая 1999
последняя редакция от 17 ноября 1999 года.
Часто задаваемые вопросы и ответы по Borland Interbase / Firebird
Материал подготовлен в Демо-центре клиент-серверных технологий. (Epsylon Technologies)
Материал не является официальной информацией компании Borland.
E-mail mailto:delphi@demo.ru
www: http://www.ibase.ru/
Телефоны: 953-13-34
источники: Borland International, Борланд АО, релиз Interbase 4.0, 4.1, 4.2, 5.0, 5.1, 5.5, 5.6, различные источники на WWW-серверах, текущая переписка, московский семинар по Delphi и конференции, листсервер ESUNIX1, листсервер mers.com.
Cоставитель: Дмитрий Кузьменко
Как явно вызвать виртуальный метод дедушки?
Как явно вызвать виртуальный метод дедушки?
Проблема в следующем. Допустим, есть иерархия классов, у которых перекрывается один и тот же виртуальный (или динамический - не важно) метод и в одной из реализаций этого метода вы хотите вызвать виртуальный метод предка своего предка. Новая объектная модель Delphi допускает только вызов методов предка (с помощью ключевого слова inherited) либо вызов методов класса с префиксом - типом класса (например, TLevel1.ClassName).
Эта проблема стандартными средствами не решается. Но сделать требуемый вызов можно. Причем способом, показанным ниже, можно вызвать любой метод для любого класса, однако, в этом случае вся ответственность за правильность работы с методами и полями ложится на программиста. Ниже в методе VirtualFunction класса TLevel3 вызывается метод класса TLevel1, а в функции Level1Always всегда вызывается метод класса TLevel1 для любого его наследника.
TLevel1= class(TComponent)
public
function VirtualFunction: string; virtual;
end;
TLevel2 = class(TLevel1)
public
function VirtualFunction: string; override;
end;
TLevel3 = class(TLevel2)
public
function VirtualFunction: string; override;
end;
function Level1Always(MyLevel: TLevel1): string;
implementation
type
PClass = ^TClass;
function TLevel1.VirtualFunction: string;
begin
Result := 'Level1';
end;
function TLevel2.VirtualFunction: string;
begin
Result := inherited VirtualFunction+' Level2';
end;
function TLevel3.VirtualFunction: string;
var
ClassOld: TClass;
begin
ClassOld := PClass(Self)^;
PClass(Self)^ := TLevel1;
Result := VirtualFunction + ' Level3';
PClass(Self)^ := ClassOld;
end;
function Level1Always(MyObject: TObject): string;
var
ClassOld: TClass;
begin
ClassOld := PClass(MyObject)^;
PClass(MyObject)^ := TLevel1;
Result := (MyObject as TLevel1).VirtualFunction;
PClass(MyObject)^ := ClassOld;
end;
Как же это работает? Стандартные так называемые объектные типы (object types - class of ...) на самом деле представляют из себя указатель на VMT (Virtual Method Table) - таблицу виртуальных методов, который (указатель) лежит по смещению 0 в экземпляре класса. Воспользовавшись этим, мы сначала сохраняем 'старый тип класса' - указатель на VMT, присваиваем ему указатель на VMT нужного класса, делаем вызов и восстанавливаем все как было. Причем нигде не требуется, чтобы один из этих классов был бы порожден от другого, т.е. функция Level1Always вызовет требуемый метод вообще для любого экземпляра любого класса.
Если в функции Level1Always сделать попробовать вызов
Result := MyObject.VirtualFunction;
то будет ошибка на стации компиляции, так как у класса TObject нет метода VirtualFunction. Другой вызов
Result := (MyObject as TLevel3).VirtualFunction;
будет пропущен компилятором, но вызовет Run-time ошибку, даже если передается экземпляр класса TLevel3 или один из его потомком, так как информация о типе объекта меняется. Динамически распределяемые (dynamic) методы можно вызывать точно таким же образом, т.к. информация о них тоже хранится в VMT. Статические методы объектов вызываются гораздо более простым способом, например
var
MyLevel3: TLevel3;
...
(MyLevel3 as TLevel1).SomeMethode;
вызовет метод класса TLevel1 даже если у MyLevel3 есть свой такой же метод.
Copyright © 1996 Epsylon Technologies
Взято из
FAQ Epsylon Technologies (095)-913-5608; (095)-913-2934; (095)-535-5349Как экспортировать процедуру в EXE файле
Как экспортировать процедуру в EXE файле
В DPR файле совершенно обычного проэкта дельфи можно указать функцию (процедуру) и объявить ее как экспортируемую - синтаксис точно такой-же как при создании стандартной DLL. С таким довеском EXE совершенно нормально компиллируется и работает и как EXE и как DLL (т.е. из нее можно импортировать описанные функции). Зачем это нужно? Была одна задача - делал консоль которая связывала воедино несколько приложений, так экспортные функции позволяли существенно расширять функциональность комплекса. Правда такой EXE все же имеет недостаток - EXE упаковщики сохраняют исполняемую часть и неправильно упаковывают экспортированную... Кроме того могут быть проблемы передачи строковых параметров.
Автор ответа: Vit
Взято с Vingrad.ru
Как экспортировать содержимое DBGrid в Excel или ClipBoard?
Как экспортировать содержимое DBGrid в Excel или ClipBoard?
Пример dbgrid (DBGrid1) имеет всплывающее меню, которое позволяет две опции "Send to Excel" и "Copy"
// ЗАМЕЧАНИЕ: этот метод должен включать COMObj, Excel97 units
// ОБНОВЛЕНИЕ: если Вы используете Delphi 4, то замените xlWBatWorkSheet на 1 (один)
//-----------------------------------------------------------
// если toExcel = false, то экспортируем содержимое dbgrid в Clipboard
// если toExcel = true, то экспортируем содержимое dbgrid в Microsoft Excel
procedure ExportDBGrid(toExcel: Boolean);
var
bm: TBookmark;
col, row: Integer;
sline: String;
mem: TMemo;
ExcelApp: Variant;
begin
Screen.Cursor := crHourglass;
DBGrid1.DataSource.DataSet.DisableControls;
bm := DBGrid1.DataSource.DataSet.GetBookmark;
DBGrid1.DataSource.DataSet.First;
// создаём объект Excel
if toExcel then
begin
ExcelApp := CreateOleObject('Excel.Application');
ExcelApp.WorkBooks.Add(xlWBatWorkSheet);
ExcelApp.WorkBooks[1].WorkSheets[1].Name := 'Grid Data';
end;
// Сперва отправляем данные в memo
// работает быстрее, чем отправлять их напрямую в Excel
mem := TMemo.Create(Self);
mem.Visible := false;
mem.Parent := MainForm;
mem.Clear;
sline := '';
// добавляем информацию для имён колонок
for col := 0 to DBGrid1.FieldCount-1 do
sline := sline + DBGrid1.Fields[col].DisplayLabel + #9;
mem.Lines.Add(sline);
// получаем данные из memo
for row := 0 to DBGrid1.DataSource.DataSet.RecordCount-1 do
begin
sline := '';
for col := 0 to DBGrid1.FieldCount-1 do
sline := sline + DBGrid1.Fields[col].AsString + #9;
mem.Lines.Add(sline);
DBGrid1.DataSource.DataSet.Next;
end;
// копируем данные в clipboard
mem.SelectAll;
mem.CopyToClipboard;
// если необходимо, то отправляем их в Excel
// если нет, то они уже в буфере обмена
if toExcel then
begin
ExcelApp.Workbooks[1].WorkSheets['Grid Data'].Paste;
ExcelApp.Visible := true;
end;
FreeAndNil(ExcelApp);
DBGrid1.DataSource.DataSet.GotoBookmark(bm);
DBGrid1.DataSource.DataSet.FreeBookmark(bm);
DBGrid1.DataSource.DataSet.EnableControls;
Screen.Cursor := crDefault;
end;
Взято с Исходников.ru
Как экспортировать StringGrid в MS Word таблицу?
Как экспортировать StringGrid в MS Word таблицу?
uses
ComObj;
procedure TForm1.Button1Click(Sender: TObject);
var
WordApp, NewDoc, WordTable: OLEVariant;
iRows, iCols, iGridRows, jGridCols: Integer;
begin
try
// Create a Word Instance
// Word Instanz erzeugen
WordApp := CreateOleObject('Word.Application');
except
// Error...
// Fehler....
Exit;
end;
// Show Word
// Word anzeigen
WordApp.Visible := True;
// Add a new Doc
// Neues Dok einfugen
NewDoc := WordApp.Documents.Add;
// Get number of columns, rows
// Spalten, Reihen ermitteln
iCols := StringGrid1.ColCount;
iRows := StringGrid1.RowCount;
// Add a Table
// Tabelle einfugen
WordTable := NewDoc.Tables.Add(WordApp.Selection.Range, iCols, iRows);
// Fill up the word table with the Stringgrid contents
// Tabelle ausfullen mit Stringgrid Daten
for iGridRows := 1 to iRows do
for jGridCols := 1 to iCols do
WordTable.Cell(iGridRows, jGridCols).Range.Text :=
StringGrid1.Cells[jGridCols - 1, iGridRows - 1];
// Here you might want to Save the Doc, quit Word...
// Hier evtl Word Doc speichern, beenden...
// ...
// Cleanup...
WordApp := Unassigned;
NewDoc := Unassigned;
WordTable := Unassigned;
end;
Взято с сайта
Как экспортировать таблицу базы данных в ASCII-файл?
Как экспортировать таблицу базы данных в ASCII-файл?
procedure TMyTable.ExportToASCII;
var
I: Integer;
Dlg: TSaveDialog;
ASCIIFile: TextFile;
Res: Boolean;
begin
if Active then
if (FieldCount > 0) and (RecordCount > 0) then
begin
Dlg := TSaveDialog.Create(Application);
Dlg.FileName := FASCIIFileName;
Dlg.Filter := 'ASCII-Fiels (*.asc)|*.asc';
Dlg.Options := Dlg.Options+[ofPathMustExist,
ofOverwritePrompt, ofHideReadOnly];
Dlg.Title := 'Экспоритровать данные в ASCII-файл';
try
Res := Dlg.Execute;
if Res then
FASCIIFileName := Dlg.FileName;
finally
Dlg.Free;
end;
if Res then
begin
AssignFile(ASCIIFile, FASCIIFileName);
Rewrite(ASCIIFile);
First;
if FASCIIFieldNames then
begin
for I := 0 to FieldCount-1 do
begin
Write(ASCIIFile, Fields[I].FieldName);
if I <> FieldCount-1 then
Write(ASCIIFile, FASCIISeparator);
end;
Write(ASCIIFile, #13#10);
end;
while not EOF do
begin
for I := 0 to FieldCount-1 do
begin
Write(ASCIIFile, Fields[I].Text);
if I <> FieldCount-1 then
Write(ASCIIFile, FASCIISeparator);
end;
Next;
if not EOF then
Write(ASCIIFile, #13#10);
end;
CloseFile(ASCIIFile);
if IOResult <> 0 then
MessageDlg('Ошибка при создании или переписывании '+
'в ASCII-файл', mtError, [mbOK], 0);
end;
end
else
MessageDlg('Нет данных для экспортирования.',
mtInformation, [mbOK], 0)
else
MessageDlg('Таблица должна быть открытой, чтобы данные '+
'можно было экспортировать в ASCII-формат.', mtError,
[mbOK], 0);
end;
Как экспортировать таблицу в MS Word в TStringGrid?
Как экспортировать таблицу в MS Word в TStringGrid?
uses
ComObj;
procedure TForm1.Button1Click(Sender: TObject);
const
AWordDoc = 'C:\xyz\testTable.doc';
var
MSWord, Table: OLEVariant;
iRows, iCols, iGridRows, jGridCols, iNumTables, iTableChosen: Integer;
CellText: string;
InputString: string;
begin
try
MSWord := CreateOleObject('Word.Application');
except
// Error....
Exit;
end;
try
MSWord.Visible := False;
MSWord.Documents.Open(AWordDoc);
// Get number of tables in document
iNumTables := MSWord.ActiveDocument.Tables.Count;
InputString := InputBox(IntToStr(iNumTables) +
' Tables in Word Document', 'Please Enter Table Number', '1');
// Todo: Validate string for integer, range...
iTableChosen := StrToInt(InputString);
// access table
Table := MSWord.ActiveDocument.Tables.Item(iTableChosen);
// get dimensions of table
iCols := Table.Rows.Count;
iRows := Table.Columns.Count;
// adjust stringgrid columns
StringGrid1.RowCount := iCols;
StringGrid1.ColCount := iRows + 1;
// loop through cells
for iGridRows := 1 to iRows do
for jGridCols := 1 to iCols do
begin
CellText := Table.Cell(jGridCols, iGridRows).Range.FormattedText;
if not VarisEmpty(CellText) then
begin
// Remove Tabs
CellText := StringReplace(CellText,
#$D, '', [rfReplaceAll]);
// Remove linebreaks
CellText := StringReplace(CellText, #$7, '', [rfReplaceAll]);
// fill Stringgrid
Stringgrid1.Cells[iGridRows, jGridCols] := CellText;
end;
end;
//..
finally
MSWord.Quit;
end;
end;
Взято с сайта
Как экспортировать все таблицы в CSV файл?
Как экспортировать все таблицы в CSV файл?
procedureTMainForm.SaveAllTablesToCSV(DBFileName: string);
var
InfoStr,
FileName,
RecString,
WorkingDirectory: string;
OutFileList,
TableNameList: TStringList;
TableNum,
FieldNum: integer;
VT: TVarType;
begin
ADOTable1.Active := false;
WorkingDirectory := ExtractFileDir(DBFileName);
TableNameList := TStringList.Create;
OutFileList := TStringList.Create;
InfoStr := 'The following files were created' + #13#13;
ADOConnection1.GetTableNames(TableNameList, false);
for TableNum := 0 to TableNameList.Count - 1 do
begin
FileName := WorkingDirectory + '\' +
TableNameList.Strings[TableNum] + '.CSV';
Caption := 'Saving "' + ExtractFileName(FileName) + '"';
ADOTable1.TableName := TableNameList.Strings[TableNum];
ADOTable1.Active := true;
OutFileList.Clear;
ADOTable1.First;
while not ADOTable1.Eof do
begin
RecString := '';
for FieldNum := 0 to ADOTable1.FieldCount - 1 do
begin
VT := VarType(ADOTable1.Fields[FieldNum].Value);
case VT of
// just write the field if not a string
vtInteger, vtExtended, vtCurrency, vtInt64:
RecString := RecString + ADOTable1.Fields[FieldNum].AsString
else
// it IS a string so put quotes around it
RecString := RecString + '"' +
ADOTable1.Fields[FieldNum].AsString + '"';
end; { case }
// if not the last field then use a field separator
if FieldNum < (ADOTable1.FieldCount - 1) then
RecString := RecString + ',';
end; { for FieldNum }
OutFileList.Add(RecString);
ADOTable1.Next;
end; { while }
OutFileList.SaveToFile(FileName);
InfoStr := InfoStr + FileName + #13;
ADOTable1.Active := false;
end; { for TableNum }
TableNameList.Free;
OutFileList.Free;
Caption := 'Done';
ShowMessage(InfoStr);
end;
procedure TMainForm.Button1Click(Sender: TObject);
const
ConnStrA = 'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=';
ConnStrC = ';Persist Security Info=False';
ProvStr = 'Microsoft.Jet.OLEDB.4.0';
begin
OpenDialog1.InitialDir := ExtractFileDir(ParamStr(0));
if OpenDialog1.Execute then
try
ADOConnection1.ConnectionString :=
ConnStrA + OpenDialog1.FileName + ConnStrC;
ADOConnection1.Provider := ProvStr;
ADOConnection1.Connected := true;
ADOTable1.Connection := ADOConnection1;
SaveAllTablesToCSV(OpenDialog1.FileName);
except
ShowMessage('Could not Connect to ' + #13 +
'"' + OpenDialog1.FileName + '"');
Close;
end;
end;
Взято с
Delphi Knowledge BaseКак экстрагировать аудиодорожку из AVI файла?
Как экстрагировать аудиодорожку из AVI файла?
uses
{...}, vfw;
var
abort: Boolean;
{$R *.DFM}
{Vielen Dank an Jailbird, der einen groЯen Teil dieses Codes entwickelt hat
Special thanks to Jailbird, who developed a big part of this Code}
{Bitte zuerst die vfw.pas downloaden
Please download th vfw.pas first }
{Die 'SaveCallback' Funktion erlaubt es dem Benutzer den
aktuellen Prozess Status zu erfahren und den Speichervorgang
vorzeitig abzubrechen. Diese Funktion muss NICHT vom Benutzer
aufgerufen werden.
The 'SaveCallback' function allows the user to get the
process status and abort the save progress. This function
needn't to call by the user.}
function SaveCallback(nPercent: Int): Bool; pascal;
begin
Application.ProcessMessages;
Form1.Progressbar1.Position := nPercent; //Speicher Status in Prozent
//Save Status in Percent
if abort = True then
Result := True //Wenn die Funktion "True" zurьckgibt, wird der Speichervorgang fortgesetzt.
else //If then function returns "True", the Process will continue
Result := False; //Gibt sie "False" zurьck wird der Vorgang abgebrochen
end; //If it returns "False" the process will abort
{Die folgende Funktion erwartet zwei Parameter:
Inputfile: PChar
Geben Sie hier die die AVI Datei an aus welche Sie
die Audiospur extrahieren mцchten.
Outputfile: PChar
Geben Sie einen Pfad + Dateinamen einer WAVE Datei an.
In diese Datei wird die AudioSpur gespeichert.
HINWEIS:
Geben Sie nur eine WAVE Datei als Ausgabedatei an wenn
die Audiodaten in der AVI Datei unkomprimiert (als PCM WAVE)
vorliegen.
####################################################
The following function needs two parameters:
InputFile: PChar
Enter a Dir + Filename of a AVI File.
OutputFile: PChar
Enter a Dir + Filename of a WAVE File where do you want to
put the audiodata of the movie.
TIP:
Enter jus a Filename of a WAVE File if the audiodata of the
movie is in uncompressed PCM Format.
###########################################################
WICHTIG:
Stellen Sie vor dem aufrufen der Funktion 'ExtractAVISound' sicher
das die Eingabedatei (Inputfile) ьber eine AudioSpur verfьgt.
IMPORTANT:
Before calling the 'ExtractAVISound' function be sure that the
Inputfile has a audiotrace.
}
function TForm1.ExtractAVISound(InputFile, Outputfile: PChar): Boolean;
var
PFile: IAviFile;
PAvi: IAviStream;
plpOptions: PAviCompressOptions;
begin
Abort := False;
if Fileexists(StrPas(Outputfile)) then
begin
case MessageDlg('Ausgabedatei existiert bereits. Ьberschreiben?',
mtWarning, [mbYes, mbNo], 0) of
mrYes:
begin
DeleteFile(StrPas(Outputfile)); //Wichtig, da die Funktion sonst nur so viel der
end; //Datei ьberschreibt wie gebraucht wird.
//Important because the function overwrite just
//the part of the file which is needed.
mrNo:
begin
Exit;
end;
end;
end;
try //Initialisiert die API
AviFileInit; //Init the API
if AviFileOpen(PFile, Inputfile, 0, nil) <> 0 then //Цffnet eine AVI Datei
begin //Opens a AVI File
MessageDlg('Fehler beim laden des Videos.
Mцglicherweise wird die Datei von einem anderen Prozess verwendet.'
+ #13#10 +
'SchlieЯen Sie alle in Frage kommenden Anwendungen und versuchen Sie es erneut.',
mtError, [mbOK], 0);
Result := False;
Exit;
end;
if AviFileGetStream(PFile, PAvi, StreamTypeAudio, 0) <> 0 then
begin
MessageDlg(
'Fehler beim laden des AudioStreams. Bitte ьberprьfen Sie, ob dieses Video ьber einen AudioStream verfьgt.',
mtError, [mbOK], 0);
AviFileExit;
Result := False;
Exit;
end;
//Speichert den AudioStream
//Saves the AudioStream
if AviSaveV(Outputfile, nil, @SaveCallback, 1, PAvi, plpOptions) <> 0 then
begin
MessageDlg('Fehler beim Speichern des AudioStreams oder Sie haben den Speichervorgang abgebrochen.',
mtError, [mbOK], 0);
AviStreamRelease(PAvi);
AviFileExit;
Result := False;
Exit;
end;
finally
AviStreamRelease(PAvi);
AviFileExit;
end;
Result := True; //'TRUE' zurьckgeben wenn alles geklappt hat
//return 'TRUE' if all right
end;
//Beispiel zu aufrufen der Funktion:
//Example how to call the function:
procedure TForm1.Button1Click(Sender: TObject);
begin
if ExtractAVISound(PChar('D:\test.avi'), PChar('D:\test.wav')) = True then
ShowMessage('Audiospur erfolgreich gespeichert!'); // Audio sucessfully saved
else
ShowMessage('Fehler beim Speichern der Audiospur.'); // Error while saving...
end;
Взято с сайта
Как экстрагировать фрейм из AVI?
Как экстрагировать фрейм из AVI?
uses
VfW { from download };
function GrabAVIFrame(avifn: string; iFrameNumber: Integer; ToFileName: TFileName): Boolean;
var
Error: Integer;
pFile: PAVIFile;
AVIStream: PAVIStream;
gapgf: PGETFRAME;
lpbi: PBITMAPINFOHEADER;
bits: PChar;
hBmp: HBITMAP;
AviInfo: TAVIFILEINFOW;
sError: string;
TmpBmp: TBitmap;
DC_Handle: HDC;
begin
Result := False;
// Initialize the AVIFile library.
AVIFileInit;
// The AVIFileOpen function opens an AVI file
Error := AVIFileOpen(pFile, PChar(avifn), 0, nil);
if Error <> 0 then
begin
AVIFileExit;
case Error of
AVIERR_BADFORMAT: sError := 'The file couldnot be read';
AVIERR_MEMORY: sError := 'The file could not be opened because of insufficient memory.';
AVIERR_FILEREAD: sError := 'A disk error occurred while reading the file.';
AVIERR_FILEOPEN: sError := 'A disk error occurred while opening the file.';
end;
ShowMessage(sError);
Exit;
end;
// AVIFileInfo obtains information about an AVI file
if AVIFileInfo(pFile, @AVIINFO, SizeOf(AVIINFO)) <> AVIERR_OK then
begin
// Clean up and exit
AVIFileRelease(pFile);
AVIFileExit;
Exit;
end;
// Show some information about the AVI
Form1.Memo1.Lines.Add('AVI Width : ' + IntToStr(AVIINFO.dwWidth));
Form1.Memo1.Lines.Add('AVI Height : ' + IntToStr(AVIINFO.dwHeight));
Form1.Memo1.Lines.Add('AVI Length : ' + IntToStr(AVIINFO.dwLength));
// Open a Stream from the file
Error := AVIFileGetStream(pFile, AVIStream, streamtypeVIDEO, 0);
if Error <> AVIERR_OK then
begin
// Clean up and exit
AVIFileRelease(pFile);
AVIFileExit;
Exit;
end;
// Prepares to decompress video frames
gapgf := AVIStreamGetFrameOpen(AVIStream, nil);
if gapgf = nil then
begin
AVIStreamRelease(AVIStream);
AVIFileRelease(pFile);
AVIFileExit;
Exit;
end;
// Read current Frame
// AVIStreamGetFrame Returns the address of a decompressed video frame
lpbi := AVIStreamGetFrame(gapgf, iFrameNumber);
if lpbi = nil then
begin
AVIStreamGetFrameClose(gapgf);
AVIStreamRelease(AVIStream);
AVIFileRelease(pFile);
AVIFileExit;
Exit;
end;
// Show number of frames:
Form1.Memo1.Lines.Add(Format('Framstart: %d FrameEnd: %d',
[AVIStreamStart(AVIStream), AVIStreamEnd(AVIStream)]));
TmpBmp := TBitmap.Create;
try
TmpBmp.Height := lpbi.biHeight;
TmpBmp.Width := lpbi.biWidth;
bits := Pointer(Integer(lpbi) + SizeOf(TBITMAPINFOHEADER));
DC_Handle := CreateDC('Display', nil, nil, nil);
try
hBmp := CreateDIBitmap(DC_Handle, // handle of device context
lpbi^, // address of bitmap size and format data
CBM_INIT, // initialization flag
bits, // address of initialization data
PBITMAPINFO(lpbi)^, // address of bitmap color-format data
DIB_RGB_COLORS); // color-data usage
finally
DeleteDC(DC_Handle);
end;
TmpBmp.Handle := hBmp;
AVIStreamGetFrameClose(gapgf);
AVIStreamRelease(AVIStream);
AVIFileRelease(pfile);
AVIFileExit;
try
TmpBmp.SaveToFile(ToFileName);
Result := True;
except
end;
finally
TmpBmp.Free;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
// Extract Frame 3 from AVI file
GrabAVIFrame('C:\Test.avi', 3, 'c:\avifram.bmp');
end;
Взято с сайта
Как эмулировать нажатия клавиш в другой программе?
Как эмулировать нажатия клавиш в другой программе?
Как эмулировать нажатия клавиш в другой программе
http://delfaq.wallst.ru/faq/emul.html
Этот модуль является почти полным аналогом мотоду SendKeys из VB.
(Автор: Ken Henderson, email:khen@compuserve.com)
================================================================
(*
SendKeys routine for 32-bit Delphi.
Written by Ken Henderson
Copyright (c) 1995 Ken Henderson email:khen@compuserve.com
This unit includes two routines that simulate popular Visual Basic
routines: Sendkeys and AppActivate. SendKeys takes a PChar
as its first parameter and a boolean as its second, like so:
SendKeys('KeyString', Wait);
where KeyString is a string of key names and modifiers that you want
to send to the current input focus and Wait is a boolean variable or value
that indicates whether SendKeys should wait for each key message to be
processed before proceeding. See the table below for more information.
AppActivate also takes a PChar as its only parameter, like so:
AppActivate('WindowName');
where WindowName is the name of the window that you want to make the
current input focus.
SendKeys supports the Visual Basic SendKeys syntax, as documented below.
Supported modifiers:
+ = Shift
^ = Control
% = Alt
Surround sequences of characters or key names with parentheses in order to
modify them as a group. For example, '+abc' shifts only 'a', while '+(abc)' shifts
all three characters.
Supported special characters
~ = Enter
( = Begin modifier group (see above)
) = End modifier group (see above)
{ = Begin key name text (see below)
} = End key name text (see below)
Supported characters:
Any character that can be typed is supported. Surround the modifier keys
listed above with braces in order to send as normal text.
Supported key names (surround these with braces):
BKSP, BS, BACKSPACE
BREAK
CAPSLOCK
CLEAR
DEL
DELETE
DOWN
END
ENTER
ESC
ESCAPE
F1
F2
F3
F4
F5
F6
F7
F8
F9
F10
F11
F12
F13
F14
F15
F16
HELP
HOME
INS
LEFT
NUMLOCK
PGDN
PGUP
PRTSC
RIGHT
SCROLLLOCK
TAB
UP
Follow the keyname with a space and a number to send the specified key a
given number of times (e.g., {left 6}).
*)
unit sndkey32;
interface
Uses SysUtils, Windows, Messages;
function SendKeys(SendKeysString : PChar; Wait : Boolean) : Boolean;
function AppActivate(WindowName : PChar) : boolean;
{Buffer for working with PChar's}
const
WorkBufLen = 40;
var
WorkBuf : array[0..WorkBufLen] of Char;
implementation
type
THKeys = array[0..pred(MaxLongInt)] of byte;
var
AllocationSize : integer;
(*
Converts a string of characters and key names to keyboard events and
passes them to Windows.
Example syntax:
SendKeys('abc123{left}{left}{left}def{end}456{left 6}ghi{end}789', True);
*)
function SendKeys(SendKeysString : PChar; Wait : Boolean) : Boolean;
type
WBytes = array[0..pred(SizeOf(Word))] of Byte;
TSendKey = record
Name : ShortString;
VKey : Byte;
end;
const
{Array of keys that SendKeys recognizes.
if you add to this list, you must be sure to keep it sorted alphabetically
by Name because a binary search routine is used to scan it.}
MaxSendKeyRecs = 41;
SendKeyRecs : array[1..MaxSendKeyRecs] of TSendKey =
(
(Name:'BKSP'; VKey:VK_BACK),
(Name:'BS'; VKey:VK_BACK),
(Name:'BACKSPACE'; VKey:VK_BACK),
(Name:'BREAK'; VKey:VK_CANCEL),
(Name:'CAPSLOCK'; VKey:VK_CAPITAL),
(Name:'CLEAR'; VKey:VK_CLEAR),
(Name:'DEL'; VKey:VK_DELETE),
(Name:'DELETE'; VKey:VK_DELETE),
(Name:'DOWN'; VKey:VK_DOWN),
(Name:'END'; VKey:VK_END),
(Name:'ENTER'; VKey:VK_RETURN),
(Name:'ESC'; VKey:VK_ESCAPE),
(Name:'ESCAPE'; VKey:VK_ESCAPE),
(Name:'F1'; VKey:VK_F1),
(Name:'F10'; VKey:VK_F10),
(Name:'F11'; VKey:VK_F11),
(Name:'F12'; VKey:VK_F12),
(Name:'F13'; VKey:VK_F13),
(Name:'F14'; VKey:VK_F14),
(Name:'F15'; VKey:VK_F15),
(Name:'F16'; VKey:VK_F16),
(Name:'F2'; VKey:VK_F2),
(Name:'F3'; VKey:VK_F3),
(Name:'F4'; VKey:VK_F4),
(Name:'F5'; VKey:VK_F5),
(Name:'F6'; VKey:VK_F6),
(Name:'F7'; VKey:VK_F7),
(Name:'F8'; VKey:VK_F8),
(Name:'F9'; VKey:VK_F9),
(Name:'HELP'; VKey:VK_HELP),
(Name:'HOME'; VKey:VK_HOME),
(Name:'INS'; VKey:VK_INSERT),
(Name:'LEFT'; VKey:VK_LEFT),
(Name:'NUMLOCK'; VKey:VK_NUMLOCK),
(Name:'PGDN'; VKey:VK_NEXT),
(Name:'PGUP'; VKey:VK_PRIOR),
(Name:'PRTSC'; VKey:VK_PRINT),
(Name:'RIGHT'; VKey:VK_RIGHT),
(Name:'SCROLLLOCK'; VKey:VK_SCROLL),
(Name:'TAB'; VKey:VK_TAB),
(Name:'UP'; VKey:VK_UP)
);
{Extra VK constants missing from Delphi's Windows API interface}
VK_NULL=0;
VK_SemiColon=186;
VK_Equal=187;
VK_Comma=188;
VK_Minus=189;
VK_Period=190;
VK_Slash=191;
VK_BackQuote=192;
VK_LeftBracket=219;
VK_BackSlash=220;
VK_RightBracket=221;
VK_Quote=222;
VK_Last=VK_Quote;
ExtendedVKeys : set of byte =
[VK_Up,
VK_Down,
VK_Left,
VK_Right,
VK_Home,
VK_End,
VK_Prior, {PgUp}
VK_Next, {PgDn}
VK_Insert,
VK_Delete];
const
INVALIDKEY = $FFFF;
VKKEYSCANSHIFTON = $01;
VKKEYSCANCTRLON = $02;
VKKEYSCANALTON = $04;
UNITNAME = 'SendKeys';
var
UsingParens, ShiftDown, ControlDown, AltDown, FoundClose : Boolean;
PosSpace : Byte;
I, L : Integer;
NumTimes, MKey : Word;
KeyString : String[20];
procedure DisplayMessage(Message : PChar);
begin
MessageBox(0,Message,UNITNAME,0);
end;
function BitSet(BitTable, BitMask : Byte) : Boolean;
begin
Result:=ByteBool(BitTable and BitMask);
end;
procedure SetBit(var BitTable : Byte; BitMask : Byte);
begin
BitTable:=BitTable or Bitmask;
end;
procedure KeyboardEvent(VKey, ScanCode : Byte; Flags : Longint);
var
KeyboardMsg : TMsg;
begin
keybd_event(VKey, ScanCode, Flags,0);
if (Wait) then While (PeekMessage(KeyboardMsg,0,WM_KEYFIRST, WM_KEYLAST, PM_REMOVE)) do begin
TranslateMessage(KeyboardMsg);
DispatchMessage(KeyboardMsg);
end;
end;
procedure SendKeyDown(VKey: Byte; NumTimes : Word; GenUpMsg : Boolean);
var
Cnt : Word;
ScanCode : Byte;
NumState : Boolean;
KeyBoardState : TKeyboardState;
begin
if (VKey=VK_NUMLOCK) then begin
NumState:=ByteBool(GetKeyState(VK_NUMLOCK) and 1);
GetKeyBoardState(KeyBoardState);
if NumState then KeyBoardState[VK_NUMLOCK]:=(KeyBoardState[VK_NUMLOCK] and not 1)
else KeyBoardState[VK_NUMLOCK]:=(KeyBoardState[VK_NUMLOCK] or 1);
SetKeyBoardState(KeyBoardState);
exit;
end;
ScanCode:=Lo(MapVirtualKey(VKey,0));
For Cnt:=1 to NumTimes do
if (VKey in ExtendedVKeys)then begin
KeyboardEvent(VKey, ScanCode, KEYEVENTF_EXTENDEDKEY);
if (GenUpMsg) then
KeyboardEvent(VKey, ScanCode, KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP)
end else begin
KeyboardEvent(VKey, ScanCode, 0);
if (GenUpMsg) then KeyboardEvent(VKey, ScanCode, KEYEVENTF_KEYUP);
end;
end;
procedure SendKeyUp(VKey: Byte);
var
ScanCode : Byte;
begin
ScanCode:=Lo(MapVirtualKey(VKey,0));
if (VKey in ExtendedVKeys)then
KeyboardEvent(VKey, ScanCode, KEYEVENTF_EXTENDEDKEY and KEYEVENTF_KEYUP)
else KeyboardEvent(VKey, ScanCode, KEYEVENTF_KEYUP);
end;
procedure SendKey(MKey: Word; NumTimes : Word; GenDownMsg : Boolean);
begin
if (BitSet(Hi(MKey),VKKEYSCANSHIFTON)) then SendKeyDown(VK_SHIFT,1,False);
if (BitSet(Hi(MKey),VKKEYSCANCTRLON)) then SendKeyDown(VK_CONTROL,1,False);
if (BitSet(Hi(MKey),VKKEYSCANALTON)) then SendKeyDown(VK_MENU,1,False);
SendKeyDown(Lo(MKey), NumTimes, GenDownMsg);
if (BitSet(Hi(MKey),VKKEYSCANSHIFTON)) then SendKeyUp(VK_SHIFT);
if (BitSet(Hi(MKey),VKKEYSCANCTRLON)) then SendKeyUp(VK_CONTROL);
if (BitSet(Hi(MKey),VKKEYSCANALTON)) then SendKeyUp(VK_MENU);
end;
{Implements a simple binary search to locate special key name strings}
function StringToVKey(KeyString : ShortString) : Word;
var
Found, Collided : Boolean;
Bottom, Top, Middle : Byte;
begin
Result:=INVALIDKEY;
Bottom:=1;
Top:=MaxSendKeyRecs;
Found:=false;
Middle:=(Bottom+Top) div 2;
Repeat
Collided:=((Bottom=Middle) or (Top=Middle));
if (KeyString=SendKeyRecs[Middle].Name) then begin
Found:=true;
Result:=SendKeyRecs[Middle].VKey;
if (KeyString>SendKeyRecs[Middle].Name) then Bottom:=Middle
else Top:=Middle;
Middle:=(Succ(Bottom+Top)) div 2;
end;
Until (Found or Collided);
if (Result=INVALIDKEY) then DisplayMessage('Invalid Key Name');
end;
procedure PopUpShiftKeys;
begin
if (not UsingParens) then begin
if ShiftDown then SendKeyUp(VK_SHIFT);
if ControlDown then SendKeyUp(VK_CONTROL);
if AltDown then SendKeyUp(VK_MENU);
ShiftDown:=false;
ControlDown:=false;
AltDown:=false;
end;
end;
begin
AllocationSize:=MaxInt;
Result:=false;
UsingParens:=false;
ShiftDown:=false;
ControlDown:=false;
AltDown:=false;
I:=0;
L:=StrLen(SendKeysString);
if (L>AllocationSize) then L:=AllocationSize;
if (L=0) then Exit;
While (I
case SendKeysString[I] of
'(' : begin
UsingParens:=true;
Inc(I);
end;
')' : begin
UsingParens:=false;
PopUpShiftKeys;
Inc(I);
end;
'%' : begin
AltDown:=true;
SendKeyDown(VK_MENU,1,False);
Inc(I);
end;
'+' : begin
ShiftDown:=true;
SendKeyDown(VK_SHIFT,1,False);
Inc(I);
end;
'^' : begin
ControlDown:=true;
SendKeyDown(VK_CONTROL,1,False);
Inc(I);
end;
'{' : begin
NumTimes:=1;
if (SendKeysString[Succ(I)]='{') then begin
MKey:=VK_LEFTBRACKET;
SetBit(Wbytes(MKey)[1],VKKEYSCANSHIFTON);
SendKey(MKey,1,True);
PopUpShiftKeys;
Inc(I,3);
Continue;
end;
KeyString:='';
FoundClose:=false;
While (I<=L) do begin
Inc(I);
if (SendKeysString[I]='}') then begin
FoundClose:=true;
Inc(I);
Break;
end;
KeyString:=KeyString+Upcase(SendKeysString[I]);
end;
if (Not FoundClose) then begin
DisplayMessage('No Close');
Exit;
end;
if (SendKeysString[I]='}') then begin
MKey:=VK_RIGHTBRACKET;
SetBit(Wbytes(MKey)[1],VKKEYSCANSHIFTON);
SendKey(MKey,1,True);
PopUpShiftKeys;
Inc(I);
Continue;
end;
PosSpace:=Pos(' ',KeyString);
if (PosSpace<>0) then begin
NumTimes:=StrToInt(Copy(KeyString,Succ(PosSpace),Length(KeyString)-PosSpace));
KeyString:=Copy(KeyString,1,Pred(PosSpace));
end;
if (Length(KeyString)=1) then MKey:=vkKeyScan(KeyString[1])
else MKey:=StringToVKey(KeyString);
if (MKey<>INVALIDKEY) then begin
SendKey(MKey,NumTimes,True);
PopUpShiftKeys;
Continue;
end;
end;
'~' : begin
SendKeyDown(VK_RETURN,1,True);
PopUpShiftKeys;
Inc(I);
end;
else begin
MKey:=vkKeyScan(SendKeysString[I]);
if (MKey<>INVALIDKEY) then begin
SendKey(MKey,1,True);
PopUpShiftKeys;
end else DisplayMessage('Invalid KeyName');
Inc(I);
end;
end;
end;
Result:=true;
PopUpShiftKeys;
end;
{AppActivate
This is used to set the current input focus to a given window using its
name. This is especially useful for ensuring a window is active before
sending it input messages using the SendKeys function. You can specify
a window's name in its entirety, or only portion of it, beginning from
the left.
}
var
WindowHandle : HWND;
function EnumWindowsProc(WHandle: HWND; lParam: LPARAM): BOOL; export; stdcall;
const
MAX_WINDOW_NAME_LEN = 80;
var
WindowName : array[0..MAX_WINDOW_NAME_LEN] of char;
begin
{Can't test GetWindowText's return value since some windows don't have a title}
GetWindowText(WHandle,WindowName,MAX_WINDOW_NAME_LEN);
Result := (StrLIComp(WindowName,PChar(lParam), StrLen(PChar(lParam))) <> 0);
if (not Result) then WindowHandle:=WHandle;
end;
function AppActivate(WindowName : PChar) : boolean;
begin
try
Result:=true;
WindowHandle:=FindWindow(nil,WindowName);
if (WindowHandle=0) then EnumWindows(@EnumWindowsProc,Intege (PChar(WindowName)));
if (WindowHandle<>0) then begin
SendMessage(WindowHandle, WM_SYSCOMMAND, SC_HOTKEY, WindowHandle);
SendMessage(WindowHandle, WM_SYSCOMMAND, SC_RESTORE, WindowHandle);
end else Result:=false;
except
on Exception do Result:=false;
end;
end;
end.
Взято с сайта
Как качественно увеличить изображение при помощи билинейной интерполяции
Как качественно увеличить изображение при помощи билинейной интерполяции
При увеличении изображения нужно находить цвет точек, находящимися между
точками исходного изображения. Функция CopyRect, встроенная в Delphi берет
для этого цвет ближайшей точки. Увеличенное изображение получается некрасивым.
Чтобы избежать этого, используют интерполяцию.
Существует несколько видов интерполяции изображения. Наиболее простой из них - билинейный.
Изображение рассматривается как поверхность, цвет - третье измерение.
Если изображение цветное, то интерполяция проводится отдельно для трех цветов.
Для каждой точки нового изображения с координатами (xo,yo)
нужно найти четыре ближайшие точки исходного изображения.
Эти точки образуют квадрат. Через две верхние точки проводится прямая f1(x),
через две нижние - f2(x). Дальше находятся координаты для точек f1(xo) и f2(xo),
через которые проводится третья прямая f3(y). Цвет искомой точки - это f3(yo).
Этот алгоритм хорошо работает при целых или больших коэффициентах увеличения.
Но резкие границы размываются. Для уменьшения изображения этот алгоритм также не подходит.
Эта программа при нажатии на Button1 увеличивает часть изображения на экране,
а при нажатии на Button2 увеличивает открытое изображение.
procedure Interpolate(var bm: TBitMap; dx, dy: single);
var
bm1: TBitMap;
z1, z2: single;
k, k1, k2: single;
x1, y1: integer;
c: array [0..1, 0..1, 0..2] of byte;
res: array [0..2] of byte;
x, y: integer;
xp, yp: integer;
xo, yo: integer;
col: integer;
pix: TColor;
begin
bm1 := TBitMap.Create;
bm1.Width := round(bm.Width * dx);
bm1.Height := round(bm.Height * dy);
for y := 0 to bm1.Height - 1 do begin
for x := 0 to bm1.Width - 1 do begin
xo := trunc(x / dx);
yo := trunc(y / dy);
x1 := round(xo * dx);
y1 := round(yo * dy);
for yp := 0 to 1 do
for xp := 0 to 1 do begin
pix := bm.Canvas.Pixels[xo + xp, yo + yp];
c[xp, yp, 0] := GetRValue(pix);
c[xp, yp, 1] := GetGValue(pix);
c[xp, yp, 2] := GetBValue(pix);
end;
for col := 0 to 2 do begin
k1 := (c[1,0,col] - c[0,0,col]) / dx;
z1 := x * k1 + c[0,0,col] - x1 * k1;
k2 := (c[1,1,col] - c[0,1,col]) / dx;
z2 := x * k2 + c[0,1,col] - x1 * k2;
k := (z2 - z1) / dy;
res[col] := round(y * k + z1 - y1 * k);
end;
bm1.Canvas.Pixels[x,y] := RGB(res[0], res[1], res[2]);
end;
Form1.Caption := IntToStr(round(100 * y / bm1.Height)) + '%';
Application.ProcessMessages;
if Application.Terminated then Exit;
end;
bm := bm1;
end;
const
dx = 5.5;
dy = 5.5;
procedure TForm1.Button1Click(Sender: TObject);
const
w = 50;
h = 50;
var
bm: TBitMap;
can: TCanvas;
begin
bm := TBitMap.Create;
can := TCanvas.Create;
can.Handle := GetDC(0);
bm.Width := w;
bm.Height := h;
bm.Canvas.CopyRect(Bounds(0, 0, w, h), can, Bounds(0, 0, w, h));
ReleaseDC(0, can.Handle);
Interpolate(bm, dx, dy);
Form1.Canvas.Draw(0, 0, bm);
Form1.Caption := 'x: ' + FloatToStr(dx) +
' y: ' + FloatToStr(dy) +
' width: ' + IntToStr(w) +
' height: ' + IntToStr(h);
end;
procedure TForm1.Button2Click(Sender: TObject);
var
bm: TBitMap;
begin
if OpenDialog1.Execute then
bm.LoadFromFile(OpenDialog1.FileName);
Interpolate(bm, dx, dy);
Form1.Canvas.Draw(0, 0, bm);
Form1.Caption := 'x: ' + FloatToStr(dx) +
' y: ' + FloatToStr(dy) +
' width: ' + IntToStr(bm.Width) +
' height: ' + IntToStr(bm.Height);
end;
Эта программа строит заданные графики, используя модуль Recognition.
От констант left и right зависит диапазон x, от YScale зависит масштаб по y, а от k зависит качество прорисовки.
uses Recognition;
procedure TForm1.Button1Click(Sender: TObject);
const
left = -10;
right = 10;
YScale = 50;
k = 10;
var
i: integer;
Num: extended;
s: String;
XScale: single;
col: TColor;
begin
s := Edit1.Text;
preparation(s, ['x']);
XScale := PaintBox1.Width / (right - left);
randomize;
col := RGB(random(100), random(100), random(100));
for i := round(left * XScale * k) to round(right * XScale * k) do
if recogn(ChangeVar(s, 'x', i / XScale / k), Num) then
PaintBox1.Canvas.Pixels[round(i / k - left * XScale),
round(PaintBox1.Height / 2 - Num * YScale)] := col;
end;
Взято с сайта
Как клонировать процесс?
Как клонировать процесс?
{
In Linux it is possible to duplicate a process with fork. In the original
process, fork will return the handle to the duplicated process. The
duplicated process will return zero.
}
program TestFork;
{$APPTYPE CONSOLE}
uses
SysUtils,
Libc;
var
ForkedProcessHandle: __pid_t;
bForked: Boolean;
procedure ForkNow;
begin
bForked := true;
ForkedProcessHandle := fork;
end;
function IsForked: Boolean;
begin
Result := (ForkedProcessHandle = 0) and bForked;
end;
var
Lf: Integer;
begin
sigignore(SIGCHLD);
bForked := false;
WriteLn('do some stuff');
WriteLn('before fork');
ForkNow;
WriteLn('after fork - we have dublicated the process');
if IsForked then begin
WriteLn('do some stuff in forked process (wait 5s)');
for Lf := 0 to 50 do begin
Write('f');
sleep(100);
end;
end else begin
WriteLn('do stuff in original process (wait 10)');
for Lf := 0 to 100 do begin
Write('o');
sleep(100);
end;
end;
WriteLn;
if IsForked then
WriteLn('forked process end')
else
WriteLn('original process end');
end.
{
Output of this demo app:
do some stuff
before fork
after fork - we have dublicated the process
after fork - we have dublicated the process
do some stuff in forked process (wait 5s)
fdo stuff in original process (wait 10)
ooffooffooffooffooffooffooffooffooffooffooffooffooffooffooffooffooffooff
ooffooffooffooffooffooffooffoo
forked process end
ooooooooooooooooooooooooooooooooooooooooooooooooo
original process end
}
Взято с сайта
Как консольное приложение может узнать, что Винды завершаются?
Как консольное приложение может узнать, что Винды завершаются?
Автор: Nomadic
Все процессы получают сигналы CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT и CTRL_SHUTDOWN_EVENT. А делается это (грубо говоря :) так:
BOOLCtrl_Handler( DWORD Ctrl )
{
if( (Ctrl == CTRL_SHUTDOWN_EVENT) (Ctrl == CTRL_LOGOFF_EVENT) )
{
// Вау! Юзер обламывает!
}
else
{
// Тут что-от другое можно творить. А можно и не творить :-)
}
return TRUE;
}
function Ctrl_Handler(Ctrl: Longint): LongBool;
begin
if Ctrl in [CTRL_SHUTDOWN_EVENT, CTRL_LOGOFF_EVENT] then
begin
// Вау, вау
end
else
begin
// Am I creator?
end;
Result := true;
end;
А где-то в программе:
SetConsoleCtrlHandler( Ctrl_Handler, TRUE );
Таких обработчиков можно навесить кучу. Если при обработке какого-то из сообщений обработчик возвращает FALSE, то вызывается следующий обработчик. Можно настроить таких этажерок, что ого-го :-)))
Короче, смотри описание SetConsoleCtrlHandler -- там всё есть.
Взято с
Как конвертировать кодовую страницу?
Как конвертировать кодовую страницу?
All Systems (Win 95+ and WinNT4+) with MS Internet Explorer 4 and newer have a library named mlang.dll in the Winnt\System32 directory. Usually you can tell Delphi to simply import these COM Libraries. This one however, Delphi did not. I started to convert the "most wanted" interface for myself. The results I present you here.
First I give you the code for the conversion unit, that allows you simply convert any text from code page interpretation into another one. Following I will shortly discuss the code and give you a sample of how to use it.
uCodePageConverter
{** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Unit Name : uCodePageConverter
* Autor : Daniel Wischnewski
* Copyright : Copyright © 2002 by gate(n)etwork. All Right Reserved.
* Urheber : Daniel Wischnewski
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
unit uCodePageConverter;
interface
uses
Windows;
const
IID_MLangConvertCharset: TGUID = '{D66D6F98-CDAA-11D0-B822-00C04FC9B31F}';
CLASS_MLangConvertCharset: TGUID = '{D66D6F99-CDAA-11D0-B822-00C04FC9B31F}';
type
tagMLCONVCHARF = DWORD;
const
MLCONVCHARF_AUTODETECT: tagMLCONVCHARF = 1;
MLCONVCHARF_ENTITIZE: tagMLCONVCHARF = 2;
type
tagCODEPAGE = UINT;
const
CODEPAGE_Thai: tagCODEPAGE = 0874;
CODEPAGE_Japanese: tagCODEPAGE = 0932;
CODEPAGE_Chinese_PRC: tagCODEPAGE = 0936;
CODEPAGE_Korean: tagCODEPAGE = 0949;
CODEPAGE_Chinese_Taiwan: tagCODEPAGE = 0950;
CODEPAGE_UniCode: tagCODEPAGE = 1200;
CODEPAGE_Windows_31_EastEurope: tagCODEPAGE = 1250;
CODEPAGE_Windows_31_Cyrillic: tagCODEPAGE = 1251;
CODEPAGE_Windows_31_Latin1: tagCODEPAGE = 1252;
CODEPAGE_Windows_31_Greek: tagCODEPAGE = 1253;
CODEPAGE_Windows_31_Turkish: tagCODEPAGE = 1254;
CODEPAGE_Hebrew: tagCODEPAGE = 1255;
CODEPAGE_Arabic: tagCODEPAGE = 1256;
CODEPAGE_Baltic: tagCODEPAGE = 1257;
type
IMLangConvertCharset = interface
['{D66D6F98-CDAA-11D0-B822-00C04FC9B31F}']
function Initialize(
uiSrcCodePage: tagCODEPAGE; uiDstCodePage: tagCODEPAGE;
dwProperty: tagMLCONVCHARF
): HResult; stdcall;
function GetSourceCodePage(
out puiSrcCodePage: tagCODEPAGE
): HResult; stdcall;
function GetDestinationCodePage(
out puiDstCodePage: tagCODEPAGE
): HResult; stdcall;
function GetProperty(out pdwProperty: tagMLCONVCHARF): HResult; stdcall;
function DoConversion(
pSrcStr: PChar; pcSrcSize: PUINT; pDstStr: PChar; pcDstSize: PUINT
): HResult; stdcall;
function DoConversionToUnicode(
pSrcStr: PChar; pcSrcSize: PUINT; pDstStr: PWChar; pcDstSize: PUINT
): HResult; stdcall;
function DoConversionFromUnicode(
pSrcStr: PWChar; pcSrcSize: PUINT; pDstStr: PChar; pcDstSize: PUINT
): HResult; stdcall;
end;
CoMLangConvertCharset = class
class function Create: IMLangConvertCharset;
class function CreateRemote(const MachineName: string): IMLangConvertCharset;
end;
implementation
uses
ComObj;
{ CoMLangConvertCharset }
class function CoMLangConvertCharset.Create: IMLangConvertCharset;
begin
Result := CreateComObject(CLASS_MLangConvertCharset) as IMLangConvertCharset;
end;
class function CoMLangConvertCharset.CreateRemote(
const MachineName: string
): IMLangConvertCharset;
begin
Result := CreateRemoteComObject(
MachineName, CLASS_MLangConvertCharset
) as IMLangConvertCharset;
end;
end.
As you can see, I did translate only one of the many interfaces, however this one is the most efficient (according to Microsoft) and will do the job. Further I added some constants to simplify the task of finding the most important values.
When using this unit to do any code page conersions you must not forget, that the both code pages (source and destination) must be installed and supported on the computer that does the translation. OIn the computer that is going to show the result only the destination code page must be installed and supported.
To test the unit simple create a form with a memo and a button. Add the following code to the buttons OnClick event. (Do not forget to add the conversion unit to the uses clause!)
SAMPLE
procedure TForm1.Button1Click(Sender: TObject);
var
Conv: IMLangConvertCharset;
Source: PWChar;
Dest: PChar;
SourceSize, DestSize: UINT;
begin
// connect to MS multi-language lib
Conv := CoMLangConvertCharset.Create;
// initialize UniCode Translation to Japanese
Conv.Initialize(CODEPAGE_UniCode, CODEPAGE_Japanese, MLCONVCHARF_ENTITIZE);
// load source (from memo)
Source := PWChar(WideString(Memo1.Text));
SourceSize := Succ(Length(Memo1.Text));
// prepare destination
DestSize := 0;
// lets calculate size needed
Conv.DoConversionFromUnicode(Source, @SourceSize, nil, @DestSize);
// reserve memory
GetMem(Dest, DestSize);
try
// convert
Conv.DoConversionFromUnicode(Source, @SourceSize, Dest, @DestSize);
// show
Memo1.Text := Dest;
finally
// free memory
FreeMem(Dest);
end;
end;
Взято с
Delphi Knowledge BaseКак конвертировать RFC дату и обратно?
Как конвертировать RFC дату и обратно?
functionDateTimeToRfcTime(
dt: TDateTime;
iDiff: integer;
blnGMT: boolean = false): string;
{*
Explanation:
iDiff is the local offset to GMT in minutes
if blnGMT then Result is UNC time else local time
e.g. local time zone: ET = GMT - 5hr = -300 minutes
dt is TDateTime of 3 Jan 2001 5:45am
blnGMT = true -> Result = 'Wed, 03 Jan 2001 05:45:00 GMT'
blnGMT = false -> Result = 'Wed, 03 Jan 2001 05:45:00 -0500'
*}
const
Weekday: array[1..7] of string =
('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat');
Month: array[1..12] of string = (
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');
var
iDummy: Word;
iYear: Word;
iMonth: Word;
iDay: Word;
iHour: Word;
iMinute: Word;
iSecond: Word;
strZone: string;
begin
if blnGMT then
begin
dt := dt - iDiff / 1440;
strZone := 'GMT';
end
else
begin
iDiff := (iDiff div 60) * 100 + (iDiff mod 60);
if iDiff < 0 then
strZone := Format('-%.4d', [-iDiff])
else
strZone := Format('+%.4d', [iDiff]);
end;
DecodeDate(dt, iYear, iMonth, iDay);
DecodeTime(dt, iHour, iMinute, iSecond, iDummy);
Result := Format('%s, %.2d %s %4d %.2d:%.2d:%.2d %s', [
Weekday[DayOfWeek(dt)], iDay, Month[iMonth], iYear,
iHour, iMinute, iSecond, strZone]);
end;
function RfcTimeToDateTime(
strTime: string;
blnGMT: boolean = true): TDateTime;
{*
Explanation:
if blnGMT then Result is UNC time else local time
e.g. local time zone: ET = GMT - 5hr = -0500
strTime = 'Wed, 03 Jan 2001 05:45:00 -0500'
blnGMT = true -> FormatDateTime('...', Result) = '03.01.2001 10:45:00'
blnGMT = false -> FormatDateTime('...', Result) = '03.01.2001 05:45:00'
*}
const
wd = 'sun#mon#tue#wed#thu#fri#sat';
month = 'janfebmaraprmayjunjulaugsepoctnovdec';
var
s: string;
dd: Word;
mm: Word;
yy: Word;
hh: Word;
nn: Word;
ss: Word;
begin
s := LowerCase(Copy(strTime, 1, 3));
if Pos(s, wd) > 0 then
Delete(strTime, 1, Pos(' ', strTime));
s := Trim(Copy(strTime, 1, Pos(' ', strTime)));
Delete(strTime, 1, Length(s) + 1);
dd := StrToIntDef(s, 0);
s := LowerCase(Copy(strTime, 1, 3));
Delete(strTime, 1, 4);
mm := (Pos(s, month) div 3) + 1;
s := Copy(strTime, 1, 4);
Delete(strTime, 1, 5);
yy := StrToIntDef(s, 0);
Result := EncodeDate(yy, mm, dd);
s := strTime[1] + strTime[2];
hh := StrToIntDef(strTime[1] + strTime[2], 0);
nn := StrToIntDef(strTime[4] + strTime[5], 0);
ss := StrToIntDef(strTime[7] + strTime[8], 0);
Delete(strTime, 1, 9);
Result := Result + EncodeTime(hh, nn, ss, 0);
if (CompareText(strTime, 'gmt') <> 0) and blnGMT then
begin
hh := StrToIntDef(strTime[2] + strTime[3], 0);
nn := StrToIntDef(strTime[4] + strTime[5], 0);
if strTime[1] = '+' then
Result := Result - EncodeTime(hh, nn, 0, 0)
else
Result := Result + EncodeTime(hh, nn, 0, 0);
end;
end;
Взято с
Delphi Knowledge Basefunction RFC1123ToDateTime(Date: string): TDateTime;
var
day, month, year: Integer;
strMonth: string;
Hour, Minute, Second: Integer;
begin
try
day := StrToInt(Copy(Date, 6, 2));
strMonth := Copy(Date, 9, 3);
if strMonth = 'Jan' then month := 1
else if strMonth = 'Feb' then month := 2
else if strMonth = 'Mar' then month := 3
else if strMonth = 'Apr' then month := 4
else if strMonth = 'May' then month := 5
else if strMonth = 'Jun' then month := 6
else if strMonth = 'Jul' then month := 7
else if strMonth = 'Aug' then month := 8
else if strMonth = 'Sep' then month := 9
else if strMonth = 'Oct' then month := 10
else if strMonth = 'Nov' then month := 11
else if strMonth = 'Dec' then month := 12;
year := StrToInt(Copy(Date, 13, 4));
hour := StrToInt(Copy(Date, 18, 2));
minute := StrToInt(Copy(Date, 21, 2));
second := StrToInt(Copy(Date, 24, 2));
Result := 0;
Result := EncodeTime(hour, minute, second, 0);
Result := Result + EncodeDate(year, month, day);
except
Result := now;
end;
end;
function DateTimeToRFC1123(aDate: TDateTime): string;
const
StrWeekDay: string = 'MonTueWedThuFriSatSun';
StrMonth: string = 'JanFebMarAprMayJunJulAugSepOctNovDec';
var
Year, Month, Day: Word;
Hour, Min, Sec, MSec: Word;
DayOfWeek: Word;
begin
DecodeDate(aDate, Year, Month, Day);
DecodeTime(aDate, Hour, Min, Sec, MSec);
DayOfWeek := ((Trunc(aDate) - 2) mod 7);
Result := Copy(StrWeekDay, 1 + DayOfWeek * 3, 3) + ', ' +
Format('%2.2d %s %4.4d %2.2d:%2.2d:%2.2d',
[Day, Copy(StrMonth, 1 + 3 * (Month - 1), 3),
Year, Hour, Min, Sec]);
end;
Взято с сайта
Как конвертировать RGB в TColor
Как конвертировать RGB в TColor
functionRGBToColor(R,G,B:Byte): TColor;
begin
Result:=B Shl 16 Or
G Shl 8 Or
R;
end;
Взято с Исходников.ru
RGB -> TColor
RGB(r,g,b:byte):tcolor
TColor -> RGB
GetRValue(color:tcolor)
GetGValue(color:tcolor)
GetBValue(color:tcolor)
Автор ответа: Vit
Взято с Vingrad.ru
Как конвертировать виртуальную клавишу в ASCII код?
Как конвертировать виртуальную клавишу в ASCII код?
Получаем символ, соответствующий виртуальной клавише:
function GetCharFromVKey(vkey: Word): string;
var
keystate: TKeyboardState;
retcode: Integer;
begin
Win32Check(GetKeyboardState(keystate));
SetLength(Result, 2);
retcode := ToAscii(vkey,
MapVirtualKey(vkey, 0),
keystate, @Result[1],
0);
case retcode of
0: Result := '';
1: SetLength(Result, 1);
2: ;
else
Result := '';
end;
end;
{
Использование:
procedure TForm1.Edit1KeyDown
(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
ShowMessage(GetCharFromVKey(Key));
end;
}
Взято с Исходников.ru
Как конвертировать WideString в String?
Как конвертировать WideString в String?
{:Converts Unicode string to Ansi string using specified code page.
@param ws Unicode string.
@param codePage Code page to be used in conversion.
@returns Converted ansi string.
}
function WideStringToString(const ws: WideString; codePage: Word): AnsiString;
var
l: integer;
begin
if ws = ' then
Result := '
else
begin
l := WideCharToMultiByte(codePage,
WC_COMPOSITECHECK or WC_DISCARDNS or WC_SEPCHARS or WC_DEFAULTCHAR,
@ws[1], - 1, nil, 0, nil, nil);
SetLength(Result, l - 1);
if l > 1 then
WideCharToMultiByte(codePage,
WC_COMPOSITECHECK or WC_DISCARDNS or WC_SEPCHARS or WC_DEFAULTCHAR,
@ws[1], - 1, @Result[1], l - 1, nil, nil);
end;
end; { WideStringToString }
{:Converts Ansi string to Unicode string using specified code page.
@param s Ansi string.
@param codePage Code page to be used in conversion.
@returns Converted wide string.
}
function StringToWideString(const s: AnsiString; codePage: Word): WideString;
var
l: integer;
begin
if s = ' then
Result := '
else
begin
l := MultiByteToWideChar(codePage, MB_PRECOMPOSED, PChar(@s[1]), - 1, nil, 0);
SetLength(Result, l - 1);
if l > 1 then
MultiByteToWideChar(CodePage, MB_PRECOMPOSED, PChar(@s[1]),
- 1, PWideChar(@Result[1]), l - 1);
end;
end; { StringToWideString }
Взято с сайта
Как копировать и удалять таблицы?
Как копировать и удалять таблицы?
Here is an example of a routine that I use for copying and deleting tables. It uses DB, DBTables, DbiProcs,DbiErrs, and DbiTypes.
You simply provide the directory to copy from, the source table name, the directory to copy to, and the destination table name, and the BDE will copy the entire table, indexes and all to the new file.
The delete function takes the path to delete from and the name of the table to delete, the BDE takes care of deleting all associated files (indexes, etc.).
These procedures have been pulled off a form of mine, and I've edited them to remove some dependencies that existed with that form. They should now be completely stand-alone.
procedureTConvertForm.CopyTable(FromDir, SrcTblName, ToDir, DestTblName: string);
var
DBHandle: HDBIDB;
ResultCode: DBIResult;
Src, Dest, Err: array[0..255] of Char;
SrcTbl, DestTbl: TTable;
begin
SrcTbl := TTable.Create(Application);
DestTbl := TTable.Create(Application);
try
SrcTbl.DatabaseName := FromDir;
SrcTbl.TableName := SrcTblName;
SrcTbl.Open;
DBHandle := SrcTbl.DBHandle;
SrcTbl.Close;
ResultCode := DbiCopyTable(DBHandle, false,
StrPCopy(Src, FromDir + '\' + SrcTblName), nil,
StrPCopy(Dest, ToDir + '\' + DestTblName));
if ResultCode <> DBIERR_NONE then
begin
DbiGetErrorString(ResultCode, Err);
raise EDatabaseError.Create('While copying ' +
FromDir + '\' + SrcTblName + ' to ' +
ToDir + '\' + DestTblName + ', the '
+ ' database engine generated the error '''
+ StrPas(Err) + '''');
end;
finally
SrcTbl.Free;
DestTbl.Free;
end;
end;
procedure TConvertForm.DeleteTable(Dir, TblName: string);
var
DBHandle: HDBIDB;
ResultCode: DBIResult;
tbl, Err: array[0..255] of Char;
SrcTbl, DestTbl: TTable;
begin
SrcTbl := TTable.Create(Application);
try
SrcTbl.DatabaseName := Dir;
SrcTbl.TableName := TblName;
SrcTbl.Open;
DBHandle := SrcTbl.DBHandle;
SrcTbl.Close;
ResultCode := DbiDeleteTable(DBHandle,
StrPCopy(Tbl, Dir + '\' + TblName), nil);
if ResultCode <> DBIERR_NONE then
begin
DbiGetErrorString(ResultCode, Err);
raise EDatabaseError.Create('While deleting ' +
Dir + '\' + TblName + ', the database ' +
'engine generated the error ''' + StrPas(Err) + '''');
end;
finally
SrcTbl.Free;
end;
end;
Взято с
Delphi Knowledge BaseКак копировать и вставлять Bitmap через буфер обмена?
Как копировать и вставлять Bitmap через буфер обмена?
Некоторые функции для копирования и вставки Bitmap-объектов через буфер обмена.
function CopyClipToBuf(DC: HDC; Left, Top, Width, Height: Integer; Rop: LongInt; var CopyDC: HDC; var CopyBitmap: HBitmap): Boolean;
var
TempBitmap: HBitmap;
begin
Result := False;
CopyDC := 0;
CopyBitmap := 0;
if DC <> 0 then
begin
CopyDC := CreateCompatibleDC(DC);
if CopyDC <> 0 then
begin
CopyBitmap := CreateCompatibleBitmap(DC, Width, Height);
if CopyBitmap <> 0 then
begin
TempBitmap := CopyBitmap;
CopyBitmap := SelectObject(CopyDC, CopyBitmap);
Result := BitBlt(CopyDC, 0, 0, Width, Height, DC, Left, Top, Rop);
CopyBitmap := TempBitmap;
end;
end;
end;
end;
function CopyBufToClip(DC: HDC; var CopyDC: HDC; var CopyBitmap: HBitmap;
Left, Top, Width, Height: Integer;
Rop: LongInt; DeleteObjects: Boolean): Boolean;
var
TempBitmap: HBitmap;
begin
Result := False;
if (DC <> 0) and (CopyDC <> 0) and (CopyBitmap <> 0) then
begin
TempBitmap := CopyBitmap;
CopyBitmap := SelectObject(DC, CopyBitmap);
Result := BitBlt(DC, Left, Top, Width, Height, CopyDC, 0, 0, Rop);
CopyBitmap := TempBitmap;
if DeleteObjects then
begin
DeleteDC(CopyDC);
DeleteObject(CopyBitmap);
end;
end;
end;
Как копировать и вставлять TreeNode?
Как копировать и вставлять TreeNode?
var
SL : TStringList;
procedure TForm1.CutBtnClick(Sender: TObject);
var
i, j, StartLevel : integer;
TNSel : TTreeNode;
begin
TNSel := TreeView1.Selected;
if TNSel <> nil then begin
StartLevel := TNSel.Level;
i := TNSel.AbsoluteIndex;
j := i; // note for later deletion
if SL = nil then
SL := TStringList.Create
else
SL.Clear;
SL.AddObject(TNSel.Text, pointer(0));
inc(i);
with TreeView1 do begin
while Items[i].Level > StartLevel do begin
{stop before next sibling to top node\}
SL.AddObject(Items[i].Text, pointer(Items[i].Level - StartLevel));
inc(i);
end; {while Items[i].Level > StartLevel\}
Items[j].Delete;
end; {with TreeView1\}
end; {if TNSel <> nil\}
end;
procedure TForm1.PasteBtnClick(Sender: TObject);
var
i, Level : integer;
TNSel, TN : TTreeNode;
begin
with TreeView1 do begin
TNSel := Selected;
if TNSel <> nil then begin
TN := Items.Insert(TNSel, SL.Strings[0]);
Level := integer(SL.Objects[0]); // should be 0
for i := 1 to SL.Count - 1 do begin
if integer(SL.Objects[i]) < Level then begin
{go up one level\}
TN := TN.Parent;
Level := integer(SL.Objects[i]);
end; {if integer(SL.Objects[i]) < Level\}
if Level = integer(SL.Objects[i]) then
{same level\}
TN := Items.Add(TN, SL.Strings[i])
else begin
{go down one level\}
TN := Items.AddChild(TN, SL.Strings[i]);
Level := integer(SL.Objects[i]);
end; {if Level = integer(SL.Objects[i])\}
end; {for i := 1 to SL.Count - 1\}
end; {if TNSel <> nil\}
end; {with TreeView1\}
end;
Взято с
Как копировать образ экрана в файл
Как копировать образ экрана в файл
На форме у меня стоит TImage (его можно сделать невидимым)
uses JPEG;
...
var i: TJPEGImage;
begin
try
i := TJPEGImage.create;
try
i.CompressionQuality := 100;
image.Width := screen.width;
image.height := screen.height;
DWH := GetDesktopWindow;
GetWindowRect(DWH, DRect);
DescDC := GetDeviceContext(DWH);
Canv.Handle := DescDC;
DRect.Left := 0;
DRect.Top := 0;
DRect.Right := screen.Width;
DRect.Bottom := screen.Height;
Image.Canvas.CopyRect(DRect, Canv, DRect);
i.assign(Image.Picture.Bitmap);
I.SaveToFile('M:\MyFile.jpg');
finally
i.free;
end;
except
end;
Типы использованных переменных:
Dwh : HWND;
DRect: TRect;
DescDC : HDC;
Canv : TCanvas;
Автор ответа: Vit
Взято с Vingrad.ru
Как копировать RTF текст в буффер обмена?
Как копировать RTF текст в буффер обмена?
{
You have to dig into the Rich Text Format if you want to copy text to the
clipboard that has format information embedded. The application you paste
this text into has to understand RTF, or the formatting will not show up.
OK, the first step is to register a clipboard format for RTF, since this is
not a predefined format:
}
Var
CF_RTF : Word;
CF_RTF := RegisterClipboardFormat('Rich Text Format');
{
The format name has to appear as typed above, this is the name used by MS
Word for Windows and similar MS products.
NOTE: The Richedit Unit declares a constant CF_RTF, which is NOT the
clipboard format handle but the string you need to pass to RegisterClipboard
format! So you can place Richedit into your uses clause and change the line
above to
}
CF_RTF := RegisterClipboardFormat(Richedit.CF_RTF);
{
The next step is to build a RTF string with the embedded format information.
You will get a shock if you inspect the mess of RTF stuff W4W will put into
the clipboard if you copy just a few characters (the app below allows you to
inspect the clipboard), but you can get away with a lot less. The bare
minimum would be something like this (inserts an underlined 44444):
}
const
testtext: PChar = '{\rtf1\ansi\pard\plain 12{\ul 44444}}';
{
The correct balance of opening and closing braces is extremely important, one
mismatch and the target app will not be able to interpret the text
correctly. If you want to control the font used for the pasted text you need
to add a fonttable (the default font is Tms Rmn, not the active font in the
target app!). See example app below, testtext2. If you want more info, the
full RTF specs can be found on www.microsoft.com, a subset is also described
in the Windows help compiler docs (hcw.hlp, comes with Delphi).
}
unit Clipfmt1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
MemFormats: TMemo;
label1: TLabel;
BtnShowFormats: TButton;
BtnGetRTF: TButton;
BtnSetRTF: TButton;
MemExample: TMemo;
procedure FormCreate(Sender: TObject);
procedure BtnShowFormatsClick(Sender: TObject);
procedure BtnGetRTFClick(Sender: TObject);
procedure BtnSetRTFClick(Sender: TObject);
private
public
CF_RTF: Word;
end;
var
Form1: TForm1;
implementation
uses Clipbrd;
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
// register clipboard format rtf
CF_RTF := RegisterClipboardFormat('Rich Text Format');
if CF_RTF = 0 then
begin
ShowMessage('Unable to register the Rich Text clipboard format!');
Application.Terminate;
end;
BtnShowFormats.Click;
end;
// show clipboard formats
procedure TForm1.BtnShowFormatsClick(Sender: TObject);
var
buf: array [0..60] of Char;
n: Integer;
fmt: Word;
Name: string[30];
begin
MemFormats.Clear;
for n := 0 to Clipboard.FormatCount - 1 do
begin
fmt := Clipboard.Formats[n];
if GetClipboardFormatName(fmt, buf, Pred(SizeOf(buf))) <> 0 then
MemFormats.Lines.Add(StrPas(buf))
else
begin
case fmt of
1: Name := 'CF_TEXT';
2: Name := 'CF_BITMAP';
3: Name := 'CF_METAFILEPICT';
4: Name := 'CF_SYLK';
5: Name := 'CF_DIF';
6: Name := 'CF_TIFF';
7: Name := 'CF_OEMTEXT';
8: Name := 'CF_DIB';
9: Name := 'CF_PALETTE';
10: Name := 'CF_PENDATA';
11: Name := 'CF_RIFF';
12: Name := 'CF_WAVE';
13: Name := 'CF_UNICODETEXT';
14: Name := 'CF_ENHMETAFILE';
15: Name := 'CF_HDROP (Win 95)';
16: Name := 'CF_LOCALE (Win 95)';
17: Name := 'CF_MAX (Win 95)';
$0080: Name := 'CF_OWNERDISPLAY';
$0081: Name := 'CF_DSPTEXT';
$0082: Name := 'CF_DSPBITMAP';
$0083: Name := 'CF_DSPMETAFILEPICT';
$008E: Name := 'CF_DSPENHMETAFILE';
$0200..$02FF: Name := 'private format';
$0300..$03FF: Name := 'GDI object';
else
Name := 'unknown format';
end;
MemFormats.Lines.Add(Name);
end;
end;
end;
// get rtf code from clipboard
procedure TForm1.BtnGetRTFClick(Sender: TObject);
var
MemHandle: THandle;
begin
with Clipboard do
begin
Open;
try
if HasFormat(CF_RTF) then
begin
MemHandle := GetAsHandle(CF_RTF);
MemExample.SetTextBuf(GlobalLock(MemHandle));
GlobalUnlock(MemHandle);
end
else
MessageDlg('The clipboard contains no RTF text!',
mtError, [mbOK], 0);
finally
Close;
end;
end;
end;
// set rtf code to the clipboard
procedure TForm1.BtnSetRTFClick(Sender: TObject);
const
testtext: PChar = '{\rtf1\ansi\pard\plain 12{\ul 44444}}';
testtext2: PChar = '{\rtf1\ansi' +
'\deff4\deflang1033{\fonttbl{\f4\froman\fcharset0\fprq2 Times New Roman;}}' +
'\pard\plain 12{\ul 44444}}';
flap: Boolean = False;
var
MemHandle: THandle;
rtfstring: PChar;
begin
with Clipboard do
begin
if flap then
rtfstring := testtext2
else
rtfstring := testtext;
flap := not flap;
MemHandle := GlobalAlloc(GHND or GMEM_SHARE, StrLen(rtfstring) + 1);
if MemHandle <> 0 then
begin
StrCopy(GlobalLock(MemHandle), rtfstring);
GlobalUnlock(MemHandle);
Open;
try
AsText := '1244444';
SetAsHandle(CF_RTF, MemHandle);
finally
Close;
end;
end
else
MessageDlg('Global Alloc failed!',
mtError, [mbOK], 0);
end;
end;
end.
Взято с сайта
Как копировать векторное изображение?
Как копировать векторное изображение?
procedureTForm1.Button1Click(Sender: TObject);
var
mf: TMetaFile;
mfc: TMetaFileCanvas;
i: integer;
ClipBrdFormat: word;
data: cardinal;
palette: hPalette;
p: array [0..90] of TPoint;
begin
mf := TMetaFile.Create;
mf.Width := 100;
mf.Height := 100;
mfc := TMetafileCanvas.Create(mf, 0);
with mfc do
begin
Pen.Color := clBlack;
FrameRect(ClipRect);
MoveTo(0, 50);
LineTo(100, 50);
LineTo(95, 48);
MoveTo(100, 50);
LineTo(95, 52);
MoveTo(50, 100);
LineTo(50, 0);
LineTo(48, 5);
MoveTo(50, 0);
LineTo(52, 5);
Brush.Style := bsClear;
Font.name := 'arial';
Font.Size := 6;
TextOut(55, 0, 'Y');
TextOut(95, 38, 'X');
Pen.Color := clRed;
for i := low(p) to high(p) do
p[i] := Point(i, round(50 - 30 * sin((i - 50) / 5)));
Polyline(p);
end;
mfc.Free;
mf.SaveToClipboardFormat(ClipBrdFormat, data, palette);
OpenClipboard(Application.Handle);
EmptyClipboard;
SetClipboardData(ClipBrdFormat, data);
CloseClipboard;
mf.Inch := 200;
Form1.Canvas.Draw(0, 0, mf);
mf.Free;
end;
Взято с
Как корректно прервать выполнение SQL-запроса?
Как корректно прервать выполнение SQL-запроса?
Дает ли Delphi возможность корректно прервать выполнение SQL-запроса к серверу Oracle с помощью BDE? Например, чтобы при использовании с SQL Plus после отправки SQL-запроса на выполнение на экране появлялось окно с кнопкой Cancel, которое давало бы возможность в любой момент прервать выполнение этого запроса?
Насколько мне известно, для этой цели лучше всего использовать функции Oracle Call Interface (низкоуровневый API Oracle). В комплекте поставки Oracle есть соответствующие примеры для C, и переписать их на Pascal несложно.
Некоторые драйверы SQL Link позволяют прекратить выполнение запроса, если время его выполнения превышает заранее заданное значение (параметр MAX QUERY TIME соответствующего драйвера). Однако драйвер ORACLE, к сожалению, в их число не входит.
Взято из
Как локализовать (русифицировать) ресурсы какого-либо пакета (runtime package)?
Как локализовать (русифицировать) ресурсы какого-либо пакета (runtime package)?
1) Вынимаете pесуpсы из этого модуля.
2) Пеpеводите их на дpугой язык. (напpимеp pусский)
3) Создаете в Delphi свой пpоект Dll-ки (с именем того модуля, из котоpого вы
вынули pесуpсы, напpимеp vcl30), в котоpый включаете _пеpеведенные_
pесуpсы:
{$R vcl30rus.res}
4) Собиpаете все это.
5) Пеpеименовываете полученную vcl30.Dll в vcl30.rus и кидаете ее в System.
Если вы хотите, пpиложение "говоpило" по pусски только тогда, когда в
pегиональных установках стоит Russia - то тогда это все.
Если же вы хотите, чтобы ваше пpиложение _всегда_ поднимало pусские pесуpсы,
то необходимо сделать следующее добавление в Registry:
HKEY_CURRENT_USER\SOFTWARE\Borland\Delphi\Locales
"X:\MyProject\MyApp.exe" = "rus"
Тепеpь, когда ваше пpиложение будет поднимать pakages, то всегда будут бpаться
pусские pесуpсы. Дpугие пpиложения, напpимеp Delphi - это не затpонет.
Таким обpазом можно заменять даже DFM-ки из пpоекта.
Более подpобно об этом - см Help - Index - Localizing...
Alexander Simonenko .alex@protec.kiev.ua.(2:463/249)
Как менять шрифт в RichEdit горячими клавишами?
Как менять шрифт в RichEdit горячими клавишами?
Следующий пример показывает, как можно изменять шрифт в компоненте TRichEdit при помощи следующих комбинаций клавиш:
Ctrl + B - Включает и выключает жирность (Bold) шрифта
Ctrl + I - Включает и выключает (Italic) шрифта
Ctrl + S - Включает и выключает зачёркивание (Strikeout) шрифта
Ctrl + U - Включает и выключает подчёркивание (Underline) шрифта
Замечание: Так же можно устанавливать сразу несколько типов шрифта.
Пример:
const
KEY_CTRL_B = 02;
KEY_CTRL_I = 9;
KEY_CTRL_S = 19;
KEY_CTRL_U = 21;
procedure TForm1.RichEdit1KeyPress(Sender: TObject; var Key: Char);
begin
case Ord(Key) of
KEY_CTRL_B: begin
Key := #0;
if fsBold in (Sender as TRichEdit).SelAttributes.Style then
(Sender as TRichEdit).SelAttributes.Style :=
(Sender as TRichEdit).SelAttributes.Style - [fsBold] else
(Sender as TRichEdit).SelAttributes.Style :=
(Sender as TRichEdit).SelAttributes.Style + [fsBold];
end;
KEY_CTRL_I: begin
Key := #0;
if fsItalic in
(Sender as TRichEdit).SelAttributes.Style then
(Sender as TRichEdit).SelAttributes.Style :=
(Sender as TRichEdit).SelAttributes.Style - [fsItalic]
else
(Sender as TRichEdit).SelAttributes.Style :=
(Sender as TRichEdit).SelAttributes.Style + [fsItalic];
end;
KEY_CTRL_S: begin
Key := #0;
if fsStrikeout in
(Sender as TRichEdit).SelAttributes.Style then
(Sender as TRichEdit).SelAttributes.Style :=
(Sender as TRichEdit).SelAttributes.Style - [fsStrikeout]
else
(Sender as TRichEdit).SelAttributes.Style :=
(Sender as TRichEdit).SelAttributes.Style + [fsStrikeout];
end;
KEY_CTRL_U: begin
Key := #0;
if fsUnderline in
(Sender as TRichEdit).SelAttributes.Style then
(Sender as TRichEdit).SelAttributes.Style :=
(Sender as TRichEdit).SelAttributes.Style - [fsUnderline]
else
(Sender as TRichEdit).SelAttributes.Style :=
(Sender as TRichEdit).SelAttributes.Style + [fsUnderline];
end;
end;
end;
Взято с Исходников.ru
Как мне избавиться от выскакивающего окна CPU при ошибках?
Как мне избавиться от выскакивающего окна CPU при ошибках?
HKEY_CURRENT_USER\Software\Borland\Delphi\4.0\Debugging
ViewCPUOnException=0
Взято с сайта
Как мне отправить на принтер чистый поток данных?
Как мне отправить на принтер чистый поток данных?
Под Win16 Вы можете использовать функцию SpoolFile, или
Passthrough escape, если принтер поддерживает последнее.
Под Win32 Вы можете использовать WritePrinter.
'иже пример открытия принтера и записи чистого потока данных в принтер.
Учтите, что Вы должны передать корректное имя принтера, такое, как "HP LaserJet
5MP",
чтобы функция сработала успешно.
Конечно, Вы можете включать в поток данных любые необходимые управляющие коды,
которые могут потребоваться.
uses WinSpool;
procedure WriteRawStringToPrinter(PrinterName:String; S:String);
var
Handle: THandle;
N: DWORD;
DocInfo1: TDocInfo1;
begin
if not OpenPrinter(PChar(PrinterName), Handle, nil) then
begin
ShowMessage('error ' + IntToStr(GetLastError));
Exit;
end;
with DocInfo1 do begin
pDocName := PChar('test doc');
pOutputFile := nil;
pDataType := 'RAW';
end;
StartDocPrinter(Handle, 1, @DocInfo1);
StartPagePrinter(Handle);
WritePrinter(Handle, PChar(S), Length(S), N);
EndPagePrinter(Handle);
EndDocPrinter(Handle);
ClosePrinter(Handle);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
WriteRawStringToPrinter('HP', 'Test This');
end;
(Borland FAQ N714, переведен Акжаном Абдулиным)
Взято с сайта
Как мне узнать о воздействии мыши на иконку, находящуюся на Tray?
Как мне узнать о воздействии мыши на иконку, находящуюся на Tray?
При добавлении иконки на Tray вы указывали окно - обработчик сообщения и сообщение (CallbackMessage). Теперь окно, указанное вами будет при любых событиях мыши, происходящих над иконкой получать сообщение, указанное при добавлении иконки. При этом параметры lParam и wParam будут задействованы следующим образом:
(UINT)wParam - содержит ID иконки, над которой произошло
событие
(UINT)lParam - содержит стандартное событие мыши, такое
как WM_MOUSEMOVE или WM_LBUTTONDOWN.
При этом, информация о клавишах смены регистра, так же как и местоположения события, передаваемые при стандартных " настоящих" сообщениях мыши, теряются. Hо положение курсора можно узнать функцией GetCursorPos(), а состояние клавиш смены регистра - функцией GetKeyState(), описанных в winuser.h.
Взято из FAQ:
Как можно гарантированно очистить экран в консольном приложении?
Как можно гарантированно очистить экран в консольном приложении?
Автор: Олег Кулабухов
Нужно просто использовать GetConsoleScreenBufferInfo() для ввода нескольких пустых строк.
programProject1;
{$APPTYPE CONSOLE}
uses
Windows;
{$R *.RES}
var
sbi: TConsoleScreenBufferInfo;
i: integer;
begin
Writeln('A Console Applicaiton');
Writeln('Press Enter To Clear The Screen');
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),
sbi);
Readln;
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),
sbi);
for i := 0 to sbi.dwSize.y do
writeln;
Writeln('Press Enter To End');
Readln;
end.
Взято с
Как можно из своей программы закрыть чужую?
Как можно из своей программы закрыть чужую?
PostThreadMessage(AnotherProg_MainThreadID,WM_CLOSE,0,0);
PostMessage(AnotherProg_MainWindow,WM_CLOSE,0,0);
Автор ответа: Fantasist
Взято с Vingrad.ru
Автор ответа: LENIN INC
Взято с Vingrad.ru
Как можно определить Handle окна,над которым находится мышка?
Как можно определить Handle окна,над которым находится мышка?
WindowFromPoint
ChildWindowFromPoint
Автор ответа: rhf
Взято с Vingrad.ru
Как можно открыть отчёт (в режиме Print Preview а также print direct) в MS Access ?
Как можно открыть отчёт (в режиме Print Preview а также print direct) в MS Access ?
var
Access: Variant;
begin
// Открываем Access
try
Access := GetActiveOleObject('Access.Application');
except
Access := CreateOleObject('Access.Application');
end;
Access.Visible := True;
// Открываем базу данных
// Второй параметр указывает - будет ли база открыта в Exclusive режиме
Access.OpenCurrentDatabase('C:\My Documents\Books.mdb', True);
// открываем отч?т
{Значение второго пораметра может быть одним из следующих
acViewDesign, acViewNormal, or acViewPreview. acViewNormal,
которые устанавливаются по умолчанию, для печати отч?та.
Если Вы не используете библиотеку типов, то можете определить
эти значения следующими:
const
acViewNormal = $00000000;
acViewDesign = $00000001;
acViewPreview = $00000002;
Третий параметр - это имя очереди для текущей базы данных.
Четв?ртый параметр - это строка для SQL-евского WHERE -
то есть строка SQL, минус WHERE.}
Access.DoCmd.OpenReport('Titles by Author', acViewPreview, EmptyParam,
EmptyParam);
< ... >
// Закрываем базу данных
Access.CloseCurrentDatabase;
// Закрываем Access
{const
acQuitPrompt = $00000000;
acQuitSaveAll = $00000001;
acQuitSaveNone = $00000002;}
Access.Quit(acQuitSaveAll);
end;
Как можно отменить реакию ComboBox на F4?
procedure TForm1.ComboBox1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if key=vk_F4 then key:=0;
end;
Автор ответа: Vit
Взято с Vingrad.ru
Как можно перекодировать сообщение (содержание) из Win в КОИ8-Р для отправки по EMail?
Как можно перекодировать сообщение (содержание) из Win в КОИ8-Р для отправки по EMail?
const
Koi: Array[0..66] of Char = ("T", "Ё", "ё", "А", "Б", "В", "Г", "Д", "Е", "Ж",
"З", "И", "Й", "К", "Л", "М", "Н", "О", "П", "Р",
"С", "Т", "У", "Ф", "Х", "Ц", "Ч", "Ш", "Щ", "Ъ",
"Ы", "Ь", "Э", "Ю", "Я", "а", "б", "в", "г", "д",
"е", "ж", "з", "и", "й", "к", "л", "м", "н", "о",
"п", "р", "с", "т", "у", "ф", "х", "ц", "ч", "ш",
"щ", "ъ", "ы", "ь", "э", "ю", "я");
Win: Array[0..66] of Char = ("ё", "Ё", "T", "ю", "а", "б", "ц", "д", "е", "ф",
"г", "х", "и", "й", "к", "л", "м", "н", "о", "п",
"я", "р", "с", "т", "у", "ж", "в", "ь", "ы", "з",
"ш", "э", "щ", "ч", "ъ", "Ю", "А", "Б", "Ц", "Д",
"Е", "Ф", "Г", "Х", "И", "Й", "К", "Л", "М", "Н",
"О", "П", "Я", "Р", "С", "Т", "У", "Ж", "В", "Ь",
"Ы", "З", "Ш", "Э", "Щ", "Ч", "Ъ");
function WinToKoi(Str: String): String;
var
i, j, Index: Integer;
begin
Result := ""
for i := 1 to Length(Str) do
begin
Index := -1;
for j := Low(Win) to High(Win) do
if Win[j] = Str[i] then
begin
Index := j;
Break;
end;
if Index = -1 then Result := Result + Str[i]
else Result := Result + Koi[Index];
end;
end;
function KoiToWin(Str: String): String;
var
i, j, Index: Integer;
begin
Result := ""
for i := 1 to Length(Str) do
begin
Index := -1;
for j := Low(Win) to High(Win) do
if Koi[j] = Str[i] then
begin
Index := j;
Break;
end;
if Index = -1 then Result := Result + Str[i]
else Result := Result + Win[Index];
end;
end;
procedure SendFileOnSMTP(Host: String;
Port: Integer;
Subject,
FromAddress, ToAddress,
Body,
FileName: String);
var
NMSMTP: TNMSMTP;
begin
if DelSpace(ToAddress) = "" then Exit;
if ToAddress[1] = "" then Exit;
if (DelSpace(FileName) <> "") and not FileExists(FileName) then
raise Exception.Create("SendFileOnSMTP: file not exist: " + FileName);
NMSMTP := TNMSMTP.Create(nil);
try
NMSMTP.Host := Host;
NMSMTP.Port := Port;
NMSMTP.Charset := "koi8-r"
NMSMTP.PostMessage.FromAddress := FromAddress;
NMSMTP.PostMessage.ToAddress.Text := ToAddress;
NMSMTP.PostMessage.Attachments.Text := FileName;
NMSMTP.PostMessage.Subject := Subject;
NMSMTP.PostMessage.Date := DateTimeToStr(Now);
NMSMTP.UserID := "netmaster"
NMSMTP.PostMessage.Body.Text := WinToKoi(Body);
NMSMTP.FinalHeader.Clear;
NMSMTP.TimeOut := 5000;
NMSMTP.Connect;
NMSMTP.SendMail;
NMSMTP.Disconnect;
finally
NMSMTP.Free;
end;
end;
Взято с сайта
Как можно получить звук с микрофона?
Как можно получить звук с микрофона?
unit receiver;
interface
uses mmsystem, classes;
const
samp_per_sec = 44100;
samp_cnt = samp_per_sec div 5;
buf_len = samp_cnt * 2;
type
PSample16M = ^TSample16M;
TSample16M = SmallInt;
PArrayOfSample = ^TArrayOfSample;
TArrayOfSample = array[1..samp_cnt] of TSample16M;
TReceiver = class
private
hwi: Integer;
fmt: tWAVEFORMATEX;
whdr1: WAVEHDR;
buf1: TArrayOfSample;
whdr2: WAVEHDR;
buf2: TArrayOfSample;
FStoped: Boolean;
FOnChange: TNotifyEvent;
procedure SetStoped(const Value: Boolean);
public
Peak: Integer;
Buffer: PArrayOfSample;
destructor Destroy; override;
procedure Start;
procedure Stop;
property Stoped: Boolean read FStoped write SetStoped;
property OnChange: TNotifyEvent read FOnChange write FOnChange;
end;
var rec: TReceiver;
implementation
procedure waveInProc(const hwi, uMsg, dwInstance: Integer; var hdr: WAVEHDR; const dwP2: Integer); stdcall;
const divs = samp_cnt div 100;
var
i, p: Integer;
buf: PArrayOfSample;
begin
if rec.Stoped then Exit;
case uMsg of
WIM_OPEN: begin end;
WIM_DATA: begin
rec.Buffer := PArrayOfSample(hdr.lpData);
buf := PArrayOfSample(hdr.lpData);
p := 0;
for i := 0 to samp_cnt div divs do p := p + Abs(buf[i * divs]);
rec.Peak := p div (samp_cnt div divs);
if Assigned(rec.FOnChange) then rec.FOnChange(rec);
waveInUnprepareHeader(hwi, @hdr, SizeOf(WAVEHDR));
waveInPrepareHeader(hwi, @hdr, SizeOf(WAVEHDR));
waveInAddBuffer(hwi, @hdr, SizeOf(WAVEHDR));
end;
WIM_CLOSE: begin end;
end;
end;
{ TReceiver }
destructor TReceiver.Destroy;
begin
Stoped := True;
inherited;
end;
procedure TReceiver.SetStoped(const Value: Boolean);
begin
FStoped := Value;
if Value then
begin
waveInStop(hwi);
waveInUnprepareHeader(hwi, @whdr1, SizeOf(WAVEHDR));
waveInUnprepareHeader(hwi, @whdr2, SizeOf(WAVEHDR));
waveInReset(hwi);
waveInClose(hwi);
end
else
begin
with fmt do
begin
wFormatTag := WAVE_FORMAT_PCM;
nChannels := 1;
nSamplesPerSec := samp_per_sec;
nBlockAlign := 2;
nAvgBytesPerSec := nSamplesPerSec * nBlockAlign;
wBitsPerSample := 16;
cbSize := 0;
end;
waveInOpen(@hwi, WAVE_MAPPER, @fmt, Cardinal(@waveInProc), hInstance, CALLBACK_FUNCTION);
with whdr1 do
begin
lpData := @buf1;
dwBufferLength := buf_len;
dwBytesRecorded := 0;
dwUser := 0;
dwFlags := 0;
dwLoops := 0;
lpNext := nil;
reserved := 0;
end;
waveInPrepareHeader(hwi, @whdr1, SizeOf(WAVEHDR));
waveInAddBuffer(hwi, @whdr1, SizeOf(WAVEHDR));
with whdr2 do
begin
lpData := @buf2;
dwBufferLength := buf_len;
dwBytesRecorded := 0;
dwUser := 0;
dwFlags := 0;
dwLoops := 0;
lpNext := nil;
reserved := 0;
end;
waveInPrepareHeader(hwi, @whdr2, SizeOf(WAVEHDR));
waveInAddBuffer(hwi, @whdr2, SizeOf(WAVEHDR));
waveInStart(hwi);
end;
end;
procedure TReceiver.Start;
begin
Stoped := False;
end;
procedure TReceiver.Stop;
begin
Stoped := True;
end;
initialization
rec := TReceiver.Create;
finalization
rec.Free;
end.
вот. отображать уровень можно через поле Peak при событии OnChange, там же (в этом событии) можно работать с полем Buffer в котором как раз содержется записанный сигнал.
Вся работа осуществляется через глобальную переменную rec . Возможно это не лучшая реализация с точки зрения ООП, но работает Запись происходит с глубиной 16 бит и частотой 44100 в режиме моно. После небольшой переделки все это может работать с любыми частотами и каналами и глубинами.
Автор cully
Взято с Vingrad.ru
Как изменить оконную процедуру для TForm?
Переопределите в подклассе TForm оконную процедуру WinProc класса. В примере оконная процедура переопределяется для того чтобы реагировать на сообщение WM_CANCELMODE, показывающее, что выполняется messagebox или какой-либо еще диалог.
type
TForm1 = class(TForm)
Button1: TButton;
procedure WndProc(var Message: TMessage); override;
procedure Button1Click(Sender: TObject);
private
{Private declarations}
public
{Public declarations}
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.WndProc(var Message: TMessage);
begin
if Message.Msg = WM_CANCELMODE then
begin
Form1.Caption := 'A dialog or message box has popped up';
end
else
inherited // <- остальное сделает родительская процедура
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage('Test Message');
end;
Как изменить порт для принтера?
Как изменить порт для принтера?
uses
WinSpool;
{ Function SetPrinterToPort
Parameters :
hPrinter: handle of printer to change, obtained from OpenPrinter
port: port name to use, e.g. LPT1:, COM1:, FILE:
Returns:
The name of the previous port the printer was attached to.
Description:
Changes the port a printer is attached to using Win32 API functions.
The changes made are NOT local to this process, they will affect all
other processes that try to use this printer! It is recommended to set the
port back to the old port returned by this function after
the end of the print job.
Error Conditions:
Will raise EWin32Error exceptions if SetPrinter or GetPrinter fail.
Created:
21.10.99 by P. Below}
function SetPrinterToPort(hPrinter: THandle; const port: string): string;
var
pInfo: PPrinterInfo2;
bytesNeeded: DWORD;
begin
{Figure out how much memory we need for the data buffer. Note that GetPrinter is
supposed to fail with a specific error code here. The amount of memory will
be larger than Sizeof(TPrinterInfo2) since variable amounts of data are appended
to the record}
SetLastError(NO_ERROR);
GetPrinter(hPrinter, 2, nil, 0, @bytesNeeded);
if GetLastError <> ERROR_INSUFFICIENT_BUFFER then
RaiseLastWin32Error;
pInfo := AllocMem(bytesNeeded);
try
if not GetPrinter(hPrinter, 2, pInfo, bytesNeeded, @bytesNeeded) then
RaiseLastWin32Error;
with pInfo^ do
begin
Result := pPortname;
pPortname := @port[1];
end;
if not SetPrinter(hPrinter, 2, pInfo, 0) then
RaiseLastWin32Error;
finally
FreeMem(pInfo);
end;
end;
function GetCurrentPrinterHandle: THandle;
var
Device, Driver, Port: array[0..255] of char;
hDeviceMode: THandle;
begin
Printer.GetPrinter(Device, Driver, Port, hDeviceMode);
if not OpenPrinter(@Device, Result, nil) then
RaiseLastWin32Error;
end;
Взято с
Delphi Knowledge BaseКак изменить размеры полигона?
Как изменить размеры полигона?
{... }
type
TPolygon = array of TPoint;
procedure ZoomPolygon(var Polygon: TPolygon; const Center: TPoint; const Scale: Double);
var
I: Integer;
begin
for I := 0 to High(Polygon) do
begin
Polygon[I].X := Round(Scale * (Polygon[I].X - Center.X) + Center.X);
Polygon[I].Y := Round(Scale * (Polygon[I].Y - Center.Y) + Center.Y);
end;
end;
Взято с
Delphi Knowledge BaseКак изменить шрифт hint?
Как изменить шрифт hint?
{
When the application displays a Help Hint,
it creates an instance of HintWindowClass to represent
the window used for displaying the hint.
Applications can customize this window by creating a
descendant of THintWindow and assigning it to the
HintWindowClass variable at application startup.
}
type
TMyHintWindow = class(THintWindow)
constructor Create(AOwner: TComponent); override;
end;
implementation
{....}
constructor TMyHintWindow.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
with Canvas.Font do
begin
Name := 'Arial';
Size := Size + 5;
Style := [fsBold];
end;
end;
procedure TForm2.FormCreate(Sender: TObject);
begin
HintWindowClass := TMyHintWindow;
Application.ShowHint := False;
Application.ShowHint := True;
end;
Взято с сайта
Как изменить шрифт и выравнивание в заголовке формы?
Как изменить шрифт и выравнивание в заголовке формы?
Note: The formDeactivate never gets called so when the form isn't active, sometimes the FormPaint isn't called. If anything causes the form to be repainted while in inactive, it draws correctly.
unitUnit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
type
TForm1 = class(TForm)
procedure FormPaint(Sender: TObject);
procedure FormResize(Sender: TObject);
procedure FormDeactivate(Sender: TObject);
procedure FormActivate(Sender: TObject);
private
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.FormPaint(Sender: TObject);
var
LabelHeight, LabelWidth, LabelTop: Integer;
caption_height, border3d_y, button_width, border_thickness: Integer;
MyCanvas: TCanvas;
CaptionBarRect: TRect;
begin
CaptionBarRect := Rect(0, 0, 0, 0);
MyCanvas := TCanvas.Create;
MyCanvas.Handle := GetWindowDC(Form1.Handle);
border3d_y := GetSystemMetrics(SM_CYEDGE);
button_width := GetSystemMetrics(SM_CXSIZE);
border_thickness := GetSystemMetrics(SM_CYSIZEFRAME);
caption_height := GetSystemMetrics(SM_CYCAPTION);
LabelWidth := Form1.Canvas.TextWidth(Form1.Caption);
LabelHeight := Form1.Canvas.TextHeight(Form1.Caption);
LabelTop := LabelHeight - (caption_height div 2);
CaptionBarRect.Left := border_thickness + border3d_y + button_width;
CaptionBarRect.Right := Form1.Width - (border_thickness + border3d_y)
- (button_width * 4);
CaptionBarRect.Top := border_thickness + border3d_y;
CaptionBarRect.Bottom := caption_height;
if Form1.Active then
MyCanvas.Brush.Color := clActiveCaption
else
MyCanvas.Brush.Color := clInActiveCaption;
MyCanvas.Brush.Style := bsSolid;
MyCanvas.FillRect(CaptionBarRect);
MyCanvas.Brush.Style := bsClear;
MyCanvas.Font.Color := clCaptionText;
MyCanvas.Font.Name := 'MS Sans Serif';
MyCanvas.Font.Style := MyCanvas.Font.Style + [fsBold];
DrawText(MyCanvas.Handle, PChar(' ' + Form1.Caption), Length(Form1.Caption) + 1,
CaptionBarRect, DT_CENTER or DT_SINGLELINE or DT_VCENTER);
MyCanvas.Free;
end;
procedure TForm1.FormResize(Sender: TObject);
begin
Form1.Paint;
end;
procedure TForm1.FormDeactivate(Sender: TObject);
begin
Form1.Paint;
end;
procedure TForm1.FormActivate(Sender: TObject);
begin
Form1.Paint;
end;
end.
{ ... }
type
TForm1 = class(TForm)
private
procedure WMNCPaint(var Msg: TWMNCPaint); message WM_NCPAINT;
public
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.WMNCPaint(var Msg: TWMNCPaint);
var
ACanvas: TCanvas;
begin
inherited;
ACanvas := TCanvas.Create;
try
ACanvas.Handle := GetWindowDC(Form1.Handle);
with ACanvas do
begin
Brush.Color := clActiveCaption;
Font.Name := 'Tahoma';
Font.Size := 8;
Font.Color := clred;
Font.Style := [fsItalic, fsBold];
TextOut(GetSystemMetrics(SM_CYMENU) + GetSystemMetrics(SM_CXBORDER),
Round((GetSystemMetrics(SM_CYCAPTION) - Abs(Font.Height)) / 2) + 1,
' Some Text');
end;
finally
ReleaseDC(Form1.Handle, ACanvas.Handle);
ACanvas.Free;
end;
end;
Взято с
Delphi Knowledge BaseКак изменить шрифт определённой строки в DBGrid?
Как изменить шрифт определённой строки в DBGrid?
Для этого надо воспользоваться событием OnDrawDataCell в dbgrid.
procedure TForm1.DBGrid1DrawDataCell(Sender: TObject; const Rect: TRect;
Field: TField; State: TGridDrawState);
begin
// If the record's CustNo is 4711 draw the entire row with a
// line through it. (set the font style to strike out)
if (Sender as TDBGrid).DataSource.DataSet.FieldByName('CustNo').AsString =
'4711' then
with (Sender as TDBGrid).Canvas do
begin
FillRect(Rect);
// Set the font style to StrikeOut
Font.Style := Font.Style + [fsStrikeOut];
// Draw the cell right aligned for floats + offset
if (Field.DataType = ftFloat) then
TextOut(Rect.Right - TextWidth(Field.AsString) - 3,
Rect.Top + 3, Field.AsString)
// Otherwise draw the cell left aligned + offset
else
TextOut(Rect.Left + 2, Rect.Top + 3, Field.AsString);
end;
end;
Замечание: Вышеприведённый код использует таблицу "CUSTOMER.DB", TDBGrid, TDataSource
и TTable
Взято с Исходников.ru
Как изменить системное время?
Как изменить системное время?
Функция SetSystemTime.
Обрати внимание на привилегии.
Автор ответа: podval
Взято с Vingrad.ru
1) Вариант №1
//**********************************************************
// Функция (раздел Public) SetPCSystemTime изменяет системную дату и время.
// Параметр(ы) : tDati Новая дата и время
// Возвращаемые значения: True - успешное завершение
// False - метод несработал
//************************************************************
function SetPCSystemTime(tDati: TDateTime): Boolean;
var
tSetDati: TDateTime;
vDatiBias: Variant;
tTZI: TTimeZoneInformation;
tST: TSystemTime;
begin
GetTimeZoneInformation(tTZI);
vDatiBias := tTZI.Bias / 1440;
tSetDati := tDati + vDatiBias;
with tST do
begin
wYear := StrToInt(FormatDateTime('yyyy', tSetDati));
wMonth := StrToInt(FormatDateTime('mm', tSetDati));
wDay := StrToInt(FormatDateTime('dd', tSetDati));
wHour := StrToInt(FormatDateTime('hh', tSetDati));
wMinute := StrToInt(FormatDateTime('nn', tSetDati));
wSecond := StrToInt(FormatDateTime('ss', tSetDati));
wMilliseconds := 0;
end;
SetPCSystemTime := SetSystemTime(tST);
end;
2) Вариант №2
***************************************************
Для изменения системного времени используется сложный спобой (через строки).
DateTimeToSystemTime(tSetDati,Tst); - работает быстрее и код короче
3) третий способ:
/////////////////////////////////////////////////////////////
Procedure settime(hour, min, sec, hundreths : byte); assembler;
asm
mov ch, hour
mov cl, min
mov dh, sec
mov dl, hundreths
mov ah, $2d
int $21
end;
////////////////////////////////////////////////////////////////////////
Procedure setdate(Year : word; Month, Day : byte); assembler;
asm
mov cx, year
mov dh, month
mov dl, day
mov ah, $2b
int $21
end;
Автор ответа: Pegas
Взято с Vingrad.ru
Следующие несколько строк кода позволяют установить системную дату и время без использования панели управления. Дата и время устанавливаются двумя раздельными компонентами TDateTimePicker. Дата и время декодируются и передаются в API функцию.
Из значения часа вычитается 2 для установки правильного времени. (Примечание Vit: вычитается не 2 часа а разница с Гринвичем)
procedure TfmTime.btnTimeClick(Sender: TObject);
var vsys : _SYSTEMTIME;
vYear, vMonth, vDay, vHour, vMin, vSec, vMm : Word;
begin
DecodeDate( Trunc(dtpDate.Date), vYear, vMonth, vDay );
DecodeTime( dtpTime.Time, vHour, vMin, vSec, vMm );
vMm := 0;
vsys.wYear := vYear;
vsys.wMonth := vMonth;
vsys.wDay := vDay;
vsys.wHour := ( vHour - 2 );
vsys.wMinute := vMin;
vsys.wSecond := vSec;
vsys.wMilliseconds := vMm;
vsys.wDayOfWeek := DayOfWeek( Trunc(dtpDate.Date) );
SetSystemTime( vsys );
end;
Взято с Исходников.ru
Как изменить стандартный цвет ProgressBar?
Как изменить стандартный цвет ProgressBar?
Самый простой способ, это изменить цветовую схему в свойствах экрана...
А вот при помощи следующей команды можно разукрасить ProgressBar не изменяя системных настроек:
PostMessage(ProgressBar1.Handle, $0409, 0, clGreen);
Вуаля! Теперь Progress Bar зелёный. Это всего лишь простой пример чёрной магии ;)
Взято с Исходников.ru
Как изменить уровень громкости микрофона?
Как изменить уровень громкости микрофона?
uses
MMSystem;
// Setzt die Lautstarke fur das Mikrofon
// Set the volume for the microphone
function SetMicrophoneVolume(bValue: Word): Boolean;
var {0..65535}
hMix: HMIXER;
mxlc: MIXERLINECONTROLS;
mxcd: TMIXERCONTROLDETAILS;
vol: TMIXERCONTROLDETAILS_UNSIGNED;
mxc: MIXERCONTROL;
mxl: TMixerLine;
intRet: Integer;
nMixerDevs: Integer;
begin
// Check if Mixer is available
// Uberprufen, ob ein Mixer vorhanden
nMixerDevs := mixerGetNumDevs();
if (nMixerDevs < 1) then
begin
Exit;
end;
// open the mixer
intRet := mixerOpen(@hMix, 0, 0, 0, 0);
if intRet = MMSYSERR_NOERROR then
begin
mxl.dwComponentType := MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE;
mxl.cbStruct := SizeOf(mxl);
// get line info
intRet := mixerGetLineInfo(hMix, @mxl, MIXER_GETLINEINFOF_COMPONENTTYPE);
if intRet = MMSYSERR_NOERROR then
begin
ZeroMemory(@mxlc, SizeOf(mxlc));
mxlc.cbStruct := SizeOf(mxlc);
mxlc.dwLineID := mxl.dwLineID;
mxlc.dwControlType := MIXERCONTROL_CONTROLTYPE_VOLUME;
mxlc.cControls := 1;
mxlc.cbmxctrl := SizeOf(mxc);
mxlc.pamxctrl := @mxc;
intRet := mixerGetLineControls(hMix, @mxlc, MIXER_GETLINECONTROLSF_ONEBYTYPE);
if intRet = MMSYSERR_NOERROR then
begin
{
// Microphone Name
Label1.Caption := mxlc.pamxctrl.szName;
// Min/Max Volume
Label2.Caption := IntToStr(mxc.Bounds.dwMinimum) + '->' + IntToStr(mxc.Bounds.dwMaximum);
}
ZeroMemory(@mxcd, SizeOf(mxcd));
mxcd.dwControlID := mxc.dwControlID;
mxcd.cbStruct := SizeOf(mxcd);
mxcd.cMultipleItems := 0;
mxcd.cbDetails := SizeOf(Vol);
mxcd.paDetails := @vol;
mxcd.cChannels := 1;
// vol.dwValue := mxlc.pamxctrl.Bounds.lMinimum; Set min. Volume / Minimum setzen
// vol.dwValue := mxlc.pamxctrl.Bounds.lMaximum; Set max. Volume / Maximum setzen
vol.dwValue := bValue;
intRet := mixerSetControlDetails(hMix, @mxcd,
MIXER_SETCONTROLDETAILSF_VALUE);
if intRet <> MMSYSERR_NOERROR then
ShowMessage('SetControlDetails Error');
end
else
ShowMessage('GetLineInfo Error');
end;
intRet := mixerClose(hMix);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
SetMicrophoneVolume(30000);
end;
{********************************************************}
// Enable/disable "Mute Microphone Volume"
// Ton fur Mikrofon ein/ausschalten
function SetMicrophoneVolumeMute(bMute: Boolean): Boolean;
var
hMix: HMIXER;
mxlc: MIXERLINECONTROLS;
mxcd: TMIXERCONTROLDETAILS;
vol: TMIXERCONTROLDETAILS_UNSIGNED;
mxc: MIXERCONTROL;
mxl: TMixerLine;
intRet: Integer;
nMixerDevs: Integer;
mcdMute: MIXERCONTROLDETAILS_BOOLEAN;
begin
// Check if Mixer is available
// Uberprufen, ob ein Mixer vorhanden ist
nMixerDevs := mixerGetNumDevs();
if (nMixerDevs < 1) then
begin
Exit;
end;
// open the mixer
// Mixer offnen
intRet := mixerOpen(@hMix, 0, 0, 0, 0);
if intRet = MMSYSERR_NOERROR then
begin
mxl.dwComponentType := MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE;
mxl.cbStruct := SizeOf(mxl);
// mixerline info
intRet := mixerGetLineInfo(hMix, @mxl, MIXER_GETLINEINFOF_COMPONENTTYPE);
if intRet = MMSYSERR_NOERROR then
begin
ZeroMemory(@mxlc, SizeOf(mxlc));
mxlc.cbStruct := SizeOf(mxlc);
mxlc.dwLineID := mxl.dwLineID;
mxlc.dwControlType := MIXERCONTROL_CONTROLTYPE_MUTE;
mxlc.cControls := 1;
mxlc.cbmxctrl := SizeOf(mxc);
mxlc.pamxctrl := @mxc;
// Get the mute control
// Mute control ermitteln
intRet := mixerGetLineControls(hMix, @mxlc, MIXER_GETLINECONTROLSF_ONEBYTYPE);
if intRet = MMSYSERR_NOERROR then
begin
ZeroMemory(@mxcd, SizeOf(mxcd));
mxcd.cbStruct := SizeOf(TMIXERCONTROLDETAILS);
mxcd.dwControlID := mxc.dwControlID;
mxcd.cChannels := 1;
mxcd.cbDetails := SizeOf(MIXERCONTROLDETAILS_BOOLEAN);
mxcd.paDetails := @mcdMute;
mcdMute.fValue := Ord(bMute);
// set, unset mute
// Stumsschalten ein/aus
intRet := mixerSetControlDetails(hMix, @mxcd,
MIXER_SETCONTROLDETAILSF_VALUE);
{
mixerGetControlDetails(hMix, @mxcd,
MIXER_GETCONTROLDETAILSF_VALUE);
Result := Boolean(mcdMute.fValue);
}
Result := intRet = MMSYSERR_NOERROR;
if intRet <> MMSYSERR_NOERROR then
ShowMessage('SetControlDetails Error');
end
else
ShowMessage('GetLineInfo Error');
end;
intRet := mixerClose(hMix);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
SetMicrophoneVolumeMute(False);
end;
{********************************************************}
// Enable/disable "Mute" for several mixer line sources.
uses
MMSystem;
type
TMixerLineSourceType = (lsDigital, lsLine, lsMicrophone, lsCompactDisk, lsTelephone,
lsWaveOut, lsAuxiliary, lsAnalog, lsLast);
function SetMixerLineSourceMute(AMixerLineSourceType: TMixerLineSourceType; bMute: Boolean): Boolean;
var
hMix: HMIXER;
mxlc: MIXERLINECONTROLS;
mxcd: TMIXERCONTROLDETAILS;
vol: TMIXERCONTROLDETAILS_UNSIGNED;
mxc: MIXERCONTROL;
mxl: TMixerLine;
intRet: Integer;
nMixerDevs: Integer;
mcdMute: MIXERCONTROLDETAILS_BOOLEAN;
begin
Result := False;
// Check if Mixer is available
// Uberprufen, ob ein Mixer vorhanden ist
nMixerDevs := mixerGetNumDevs();
if (nMixerDevs < 1) then
begin
Exit;
end;
// open the mixer
// Mixer offnen
intRet := mixerOpen(@hMix, 0, 0, 0, 0);
if intRet = MMSYSERR_NOERROR then
begin
ZeroMemory(@mxl, SizeOf(mxl));
case AMixerLineSourceType of
lsDigital: mxl.dwComponentType :=MIXERLINE_COMPONENTTYPE_SRC_DIGITAL;
lsLine: mxl.dwComponentType := MIXERLINE_COMPONENTTYPE_SRC_LINE;
lsMicrophone: mxl.dwComponentType :=MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE;
lsCompactDisk: mxl.dwComponentType :=MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC;
lsTelephone: mxl.dwComponentType :=MIXERLINE_COMPONENTTYPE_SRC_TELEPHONE;
lsWaveOut: mxl.dwComponentType :=MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT;
lsAuxiliary: mxl.dwComponentType :=MIXERLINE_COMPONENTTYPE_SRC_AUXILIARY;
lsAnalog : mxl.dwComponentType :=MIXERLINE_COMPONENTTYPE_SRC_ANALOG;
lsLast: mxl.dwComponentType :=MIXERLINE_COMPONENTTYPE_SRC_LAST;
end;
// mixerline info
mxl.cbStruct := SizeOf(mxl);
intRet := mixerGetLineInfo(hMix, @mxl, MIXER_GETLINEINFOF_COMPONENTTYPE);
if intRet = MMSYSERR_NOERROR then
begin
ZeroMemory(@mxlc, SizeOf(mxlc));
mxlc.cbStruct := SizeOf(mxlc);
mxlc.dwLineID := mxl.dwLineID;
mxlc.dwControlType := MIXERCONTROL_CONTROLTYPE_MUTE;
mxlc.cControls := 1;
mxlc.cbmxctrl := SizeOf(mxc);
mxlc.pamxctrl := @mxc;
// Get the mute control
// Mute control ermitteln
intRet := mixerGetLineControls(hMix, @mxlc, MIXER_GETLINECONTROLSF_ONEBYTYPE);
if intRet = MMSYSERR_NOERROR then
begin
ZeroMemory(@mxcd, SizeOf(mxcd));
mxcd.cbStruct := SizeOf(TMIXERCONTROLDETAILS);
mxcd.dwControlID := mxc.dwControlID;
mxcd.cChannels := 1;
mxcd.cbDetails := SizeOf(MIXERCONTROLDETAILS_BOOLEAN);
mxcd.paDetails := @mcdMute;
mcdMute.fValue := Ord(bMute);
// set, unset mute
// Stumsschalten ein/aus
intRet := mixerSetControlDetails(hMix, @mxcd, MIXER_SETCONTROLDETAILSF_VALUE);
{
mixerGetControlDetails(hMix, @mxcd, IXER_GETCONTROLDETAILSF_VALUE);
Result := Boolean(mcdMute.fValue);
}
Result := intRet = MMSYSERR_NOERROR;
if intRet <> MMSYSERR_NOERROR then
ShowMessage('SetControlDetails Error');
end
else
ShowMessage('GetLineInfo Error');
end;
intRet := mixerClose(hMix);
end;
end;
// Example Call; Beispielaufruf:
procedure TForm1.Button1Click(Sender: TObject);
begin
// Ton ausschalten
SetMixerLineSourceMute(lsLine, True);
end;
Взято с сайта
Как изменить заголовок чужого окна?
Как изменить заголовок чужого окна?
SetWindowText(FindWindow(nil,'Текущий заголовок'), 'Желаемый');
Взято с Исходников.ru
Автор trainer
Как изменить значение свойства компонента по имени?
Как изменить значение свойства компонента по имени?
functionGetProperty(AControl: TPersistent; AProperty: String): PPropInfo;
var
i: Integer;
props: PPropList;
typeData: PTypeData;
begin
Result := nil;
if (AControl = nil) or (AControl.ClassInfo = nil) then
Exit;
typeData := GetTypeData(AControl.ClassInfo);
if (typeData = nil) or (typeData^.PropCount = 0) then
Exit;
GetMem(props, typeData^.PropCount * SizeOf(Pointer));
try
GetPropInfos(AControl.ClassInfo, props);
for i := 0 to typeData^.PropCount - 1 do
begin
with Props^[i]^ do
if (Name = AProperty) then
result := Props^[i];
end;
finally
FreeMem(props);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
propInfo: PPropInfo;
begin
PropInfo := GetProperty(Button1.Font, 'Name');
if PropInfo <> nil then
SetStrProp(Button1.Font, PropInfo, 'Arial');
end;
Взято из
You can use RTTI to do this. Here is how to change a particular component:
procedure TForm1.BtnClick(Sender: TObject);
var
p: PPropInfo;
f: TFont;
begin
f := TFont.Create;
{Setup the font properties}
f.Name := 'Arial';
p := GetPropInfo(Sender.ClassInfo, 'Font');
if Assigned(p) then
SetOrdProp(Sender, p, Integer(f));
f.Free;
end;
To get at all the forms loop through the Screen global variable. For each form loop through its Components list calling the above procedure (or something close). If you only create your components at design time that is it. If you create some at runtime and the owner is not the form, then for each component loop through its Components list recursively to get at all the owned components.
Tip by Jeff Overcash
Взято из
I am building a routine that checks our forms for validity before deploying them. I would like to use some kind of structure that tests if a component type has access to a certain property, something like: " if (self.Controls[b] has Tag) then ...". Can anyone offer suggestions?
Here's an example of setting a string property for a component if it exists and another for an integer property:
procedureSetStringPropertyIfExists(AComp: TComponent; APropName: String;
AValue: String);
var
PropInfo: PPropInfo;
TK: TTypeKind;
begin
PropInfo := GetPropInfo(AComp.ClassInfo, APropName);
if PropInfo <> nil then
begin
TK := PropInfo^.PropType^.Kind;
if (TK = tkString) or (TK = tkLString) or (TK = tkWString) then
SetStrProp(AComp, PropInfo, AValue);
end;
end;
procedure SetIntegerPropertyIfExists(AComp: TComponent; APropName: String;
AValue: Integer);
var
PropInfo: PPropInfo;
begin
PropInfo := GetPropInfo(AComp.ClassInfo, APropName);
if PropInfo <> nil then
begin
if PropInfo^.PropType^.Kind = tkInteger then
SetOrdProp(AComp, PropInfo, AValue);
end;
end;
Tip by Xavier Pacheco
Взято из
Как извлечь иконку из EXE или DLL?
Как извлечь иконку из EXE или DLL?
Такой вот совет пришел ко мне с рассылкой "Ежедневная рассылка сайта Мастера DELPHI", думаю многим будет интересно.
Решить эту задачу нам поможет функция function ExtractIcon(hInstance, filename, iconindex):integer
где hinstance - глобальная переменная приложения, ее изменять не надо. Тип integer.
filename - имя программы или DLL из которой надо извлекать иконки. Тип pchar.
iconindex - порядковый номер иконки в файле (начинается с 0). В одном файле может находится несколько иконок. Тип integer.
Функция находится в модуле ShellApi, так что не забудьте подключить его в uses. Если эта функция возвратит ноль, значит иконок в файле нет.
Данная функция возвращает handle иконки, поэтому применять ее нужно так:
Image1.Picture.Icon.Handle:=ExtractIcon(hInstance, pchar(paramstr(0)), 0);
данное объявление нарисует в Image'e картинку вашего приложения.
Автор: Михаил Христосенко
Взято с Vingrad.ru
Как я могу работать с IB с клиентского компьютера?
Как я могу работать с IB с клиентского компьютера?
Можно использовать IB API (либо наборы компонт FreeIBComponents, IBObjects, IBX или FIBPlus, работающие напрямую с IB API), BDE+SQL Links, либо ODBC-драйвер.
Схема обмена данными между этими компонентами следующая
GDS32.DLL->IB прямое обращение к IB API
ODBC->GDS32.DLL-> IB работа через ODBC
BDE->SQL Link->GDS32.DLL->IB работа через BDE
BDE->ODBC->GDS32.DLL->IB работа через BDE, ODBC вместо SQL Link.
Практически во всех случаях вам не требуется производить какие-либо специфические настройки.
Borland Interbase / Firebird FAQ
Borland Interbase / Firebird Q&A, версия 2.02 от 31 мая 1999
последняя редакция от 17 ноября 1999 года.
Часто задаваемые вопросы и ответы по Borland Interbase / Firebird
Материал подготовлен в Демо-центре клиент-серверных технологий. (Epsylon Technologies)
Материал не является официальной информацией компании Borland.
E-mail mailto:delphi@demo.ru
www: http://www.ibase.ru/
Телефоны: 953-13-34
источники: Borland International, Борланд АО, релиз Interbase 4.0, 4.1, 4.2, 5.0, 5.1, 5.5, 5.6, различные источники на WWW-серверах, текущая переписка, московский семинар по Delphi и конференции, листсервер ESUNIX1, листсервер mers.com.
Cоставитель: Дмитрий Кузьменко
Как явно вызвать виртуальный метод дедушки?
Как явно вызвать виртуальный метод дедушки?
Проблема в следующем. Допустим, есть иерархия классов, у которых перекрывается один и тот же виртуальный (или динамический - не важно) метод и в одной из реализаций этого метода вы хотите вызвать виртуальный метод предка своего предка. Новая объектная модель Delphi допускает только вызов методов предка (с помощью ключевого слова inherited) либо вызов методов класса с префиксом - типом класса (например, TLevel1.ClassName).
Эта проблема стандартными средствами не решается. Но сделать требуемый вызов можно. Причем способом, показанным ниже, можно вызвать любой метод для любого класса, однако, в этом случае вся ответственность за правильность работы с методами и полями ложится на программиста. Ниже в методе VirtualFunction класса TLevel3 вызывается метод класса TLevel1, а в функции Level1Always всегда вызывается метод класса TLevel1 для любого его наследника.
TLevel1= class(TComponent)
public
function VirtualFunction: string; virtual;
end;
TLevel2 = class(TLevel1)
public
function VirtualFunction: string; override;
end;
TLevel3 = class(TLevel2)
public
function VirtualFunction: string; override;
end;
function Level1Always(MyLevel: TLevel1): string;
implementation
type
PClass = ^TClass;
function TLevel1.VirtualFunction: string;
begin
Result := 'Level1';
end;
function TLevel2.VirtualFunction: string;
begin
Result := inherited VirtualFunction+' Level2';
end;
function TLevel3.VirtualFunction: string;
var
ClassOld: TClass;
begin
ClassOld := PClass(Self)^;
PClass(Self)^ := TLevel1;
Result := VirtualFunction + ' Level3';
PClass(Self)^ := ClassOld;
end;
function Level1Always(MyObject: TObject): string;
var
ClassOld: TClass;
begin
ClassOld := PClass(MyObject)^;
PClass(MyObject)^ := TLevel1;
Result := (MyObject as TLevel1).VirtualFunction;
PClass(MyObject)^ := ClassOld;
end;
Как же это работает? Стандартные так называемые объектные типы (object types - class of ...) на самом деле представляют из себя указатель на VMT (Virtual Method Table) - таблицу виртуальных методов, который (указатель) лежит по смещению 0 в экземпляре класса. Воспользовавшись этим, мы сначала сохраняем 'старый тип класса' - указатель на VMT, присваиваем ему указатель на VMT нужного класса, делаем вызов и восстанавливаем все как было. Причем нигде не требуется, чтобы один из этих классов был бы порожден от другого, т.е. функция Level1Always вызовет требуемый метод вообще для любого экземпляра любого класса.
Если в функции Level1Always сделать попробовать вызов
Result := MyObject.VirtualFunction;
то будет ошибка на стации компиляции, так как у класса TObject нет метода VirtualFunction. Другой вызов
Result := (MyObject as TLevel3).VirtualFunction;
будет пропущен компилятором, но вызовет Run-time ошибку, даже если передается экземпляр класса TLevel3 или один из его потомком, так как информация о типе объекта меняется. Динамически распределяемые (dynamic) методы можно вызывать точно таким же образом, т.к. информация о них тоже хранится в VMT. Статические методы объектов вызываются гораздо более простым способом, например
var
MyLevel3: TLevel3;
...
(MyLevel3 as TLevel1).SomeMethode;
вызовет метод класса TLevel1 даже если у MyLevel3 есть свой такой же метод.
Copyright © 1996 Epsylon Technologies
Взято из
FAQ Epsylon Technologies (095)-913-5608; (095)-913-2934; (095)-535-5349Как экспортировать процедуру в EXE файле
Как экспортировать процедуру в EXE файле
В DPR файле совершенно обычного проэкта дельфи можно указать функцию (процедуру) и объявить ее как экспортируемую - синтаксис точно такой-же как при создании стандартной DLL. С таким довеском EXE совершенно нормально компиллируется и работает и как EXE и как DLL (т.е. из нее можно импортировать описанные функции). Зачем это нужно? Была одна задача - делал консоль которая связывала воедино несколько приложений, так экспортные функции позволяли существенно расширять функциональность комплекса. Правда такой EXE все же имеет недостаток - EXE упаковщики сохраняют исполняемую часть и неправильно упаковывают экспортированную... Кроме того могут быть проблемы передачи строковых параметров.
Автор ответа: Vit
Взято с Vingrad.ru
Как экспортировать содержимое DBGrid в Excel или ClipBoard?
Как экспортировать содержимое DBGrid в Excel или ClipBoard?
Пример dbgrid (DBGrid1) имеет всплывающее меню, которое позволяет две опции "Send to Excel" и "Copy"
// ЗАМЕЧАНИЕ: этот метод должен включать COMObj, Excel97 units
// ОБНОВЛЕНИЕ: если Вы используете Delphi 4, то замените xlWBatWorkSheet на 1 (один)
//-----------------------------------------------------------
// если toExcel = false, то экспортируем содержимое dbgrid в Clipboard
// если toExcel = true, то экспортируем содержимое dbgrid в Microsoft Excel
procedure ExportDBGrid(toExcel: Boolean);
var
bm: TBookmark;
col, row: Integer;
sline: String;
mem: TMemo;
ExcelApp: Variant;
begin
Screen.Cursor := crHourglass;
DBGrid1.DataSource.DataSet.DisableControls;
bm := DBGrid1.DataSource.DataSet.GetBookmark;
DBGrid1.DataSource.DataSet.First;
// создаём объект Excel
if toExcel then
begin
ExcelApp := CreateOleObject('Excel.Application');
ExcelApp.WorkBooks.Add(xlWBatWorkSheet);
ExcelApp.WorkBooks[1].WorkSheets[1].Name := 'Grid Data';
end;
// Сперва отправляем данные в memo
// работает быстрее, чем отправлять их напрямую в Excel
mem := TMemo.Create(Self);
mem.Visible := false;
mem.Parent := MainForm;
mem.Clear;
sline := '';
// добавляем информацию для имён колонок
for col := 0 to DBGrid1.FieldCount-1 do
sline := sline + DBGrid1.Fields[col].DisplayLabel + #9;
mem.Lines.Add(sline);
// получаем данные из memo
for row := 0 to DBGrid1.DataSource.DataSet.RecordCount-1 do
begin
sline := '';
for col := 0 to DBGrid1.FieldCount-1 do
sline := sline + DBGrid1.Fields[col].AsString + #9;
mem.Lines.Add(sline);
DBGrid1.DataSource.DataSet.Next;
end;
// копируем данные в clipboard
mem.SelectAll;
mem.CopyToClipboard;
// если необходимо, то отправляем их в Excel
// если нет, то они уже в буфере обмена
if toExcel then
begin
ExcelApp.Workbooks[1].WorkSheets['Grid Data'].Paste;
ExcelApp.Visible := true;
end;
FreeAndNil(ExcelApp);
DBGrid1.DataSource.DataSet.GotoBookmark(bm);
DBGrid1.DataSource.DataSet.FreeBookmark(bm);
DBGrid1.DataSource.DataSet.EnableControls;
Screen.Cursor := crDefault;
end;
Взято с Исходников.ru
Как экспортировать StringGrid в MS Word таблицу?
Как экспортировать StringGrid в MS Word таблицу?
uses
ComObj;
procedure TForm1.Button1Click(Sender: TObject);
var
WordApp, NewDoc, WordTable: OLEVariant;
iRows, iCols, iGridRows, jGridCols: Integer;
begin
try
// Create a Word Instance
// Word Instanz erzeugen
WordApp := CreateOleObject('Word.Application');
except
// Error...
// Fehler....
Exit;
end;
// Show Word
// Word anzeigen
WordApp.Visible := True;
// Add a new Doc
// Neues Dok einfugen
NewDoc := WordApp.Documents.Add;
// Get number of columns, rows
// Spalten, Reihen ermitteln
iCols := StringGrid1.ColCount;
iRows := StringGrid1.RowCount;
// Add a Table
// Tabelle einfugen
WordTable := NewDoc.Tables.Add(WordApp.Selection.Range, iCols, iRows);
// Fill up the word table with the Stringgrid contents
// Tabelle ausfullen mit Stringgrid Daten
for iGridRows := 1 to iRows do
for jGridCols := 1 to iCols do
WordTable.Cell(iGridRows, jGridCols).Range.Text :=
StringGrid1.Cells[jGridCols - 1, iGridRows - 1];
// Here you might want to Save the Doc, quit Word...
// Hier evtl Word Doc speichern, beenden...
// ...
// Cleanup...
WordApp := Unassigned;
NewDoc := Unassigned;
WordTable := Unassigned;
end;
Взято с сайта
Как экспортировать таблицу базы данных в ASCII-файл?
Как экспортировать таблицу базы данных в ASCII-файл?
procedure TMyTable.ExportToASCII;
var
I: Integer;
Dlg: TSaveDialog;
ASCIIFile: TextFile;
Res: Boolean;
begin
if Active then
if (FieldCount > 0) and (RecordCount > 0) then
begin
Dlg := TSaveDialog.Create(Application);
Dlg.FileName := FASCIIFileName;
Dlg.Filter := 'ASCII-Fiels (*.asc)|*.asc';
Dlg.Options := Dlg.Options+[ofPathMustExist,
ofOverwritePrompt, ofHideReadOnly];
Dlg.Title := 'Экспоритровать данные в ASCII-файл';
try
Res := Dlg.Execute;
if Res then
FASCIIFileName := Dlg.FileName;
finally
Dlg.Free;
end;
if Res then
begin
AssignFile(ASCIIFile, FASCIIFileName);
Rewrite(ASCIIFile);
First;
if FASCIIFieldNames then
begin
for I := 0 to FieldCount-1 do
begin
Write(ASCIIFile, Fields[I].FieldName);
if I <> FieldCount-1 then
Write(ASCIIFile, FASCIISeparator);
end;
Write(ASCIIFile, #13#10);
end;
while not EOF do
begin
for I := 0 to FieldCount-1 do
begin
Write(ASCIIFile, Fields[I].Text);
if I <> FieldCount-1 then
Write(ASCIIFile, FASCIISeparator);
end;
Next;
if not EOF then
Write(ASCIIFile, #13#10);
end;
CloseFile(ASCIIFile);
if IOResult <> 0 then
MessageDlg('Ошибка при создании или переписывании '+
'в ASCII-файл', mtError, [mbOK], 0);
end;
end
else
MessageDlg('Нет данных для экспортирования.',
mtInformation, [mbOK], 0)
else
MessageDlg('Таблица должна быть открытой, чтобы данные '+
'можно было экспортировать в ASCII-формат.', mtError,
[mbOK], 0);
end;
Как экспортировать таблицу в MS Word в TStringGrid?
Как экспортировать таблицу в MS Word в TStringGrid?
uses
ComObj;
procedure TForm1.Button1Click(Sender: TObject);
const
AWordDoc = 'C:\xyz\testTable.doc';
var
MSWord, Table: OLEVariant;
iRows, iCols, iGridRows, jGridCols, iNumTables, iTableChosen: Integer;
CellText: string;
InputString: string;
begin
try
MSWord := CreateOleObject('Word.Application');
except
// Error....
Exit;
end;
try
MSWord.Visible := False;
MSWord.Documents.Open(AWordDoc);
// Get number of tables in document
iNumTables := MSWord.ActiveDocument.Tables.Count;
InputString := InputBox(IntToStr(iNumTables) +
' Tables in Word Document', 'Please Enter Table Number', '1');
// Todo: Validate string for integer, range...
iTableChosen := StrToInt(InputString);
// access table
Table := MSWord.ActiveDocument.Tables.Item(iTableChosen);
// get dimensions of table
iCols := Table.Rows.Count;
iRows := Table.Columns.Count;
// adjust stringgrid columns
StringGrid1.RowCount := iCols;
StringGrid1.ColCount := iRows + 1;
// loop through cells
for iGridRows := 1 to iRows do
for jGridCols := 1 to iCols do
begin
CellText := Table.Cell(jGridCols, iGridRows).Range.FormattedText;
if not VarisEmpty(CellText) then
begin
// Remove Tabs
CellText := StringReplace(CellText,
#$D, '', [rfReplaceAll]);
// Remove linebreaks
CellText := StringReplace(CellText, #$7, '', [rfReplaceAll]);
// fill Stringgrid
Stringgrid1.Cells[iGridRows, jGridCols] := CellText;
end;
end;
//..
finally
MSWord.Quit;
end;
end;
Взято с сайта
Как экспортировать все таблицы в CSV файл?
Как экспортировать все таблицы в CSV файл?
procedureTMainForm.SaveAllTablesToCSV(DBFileName: string);
var
InfoStr,
FileName,
RecString,
WorkingDirectory: string;
OutFileList,
TableNameList: TStringList;
TableNum,
FieldNum: integer;
VT: TVarType;
begin
ADOTable1.Active := false;
WorkingDirectory := ExtractFileDir(DBFileName);
TableNameList := TStringList.Create;
OutFileList := TStringList.Create;
InfoStr := 'The following files were created' + #13#13;
ADOConnection1.GetTableNames(TableNameList, false);
for TableNum := 0 to TableNameList.Count - 1 do
begin
FileName := WorkingDirectory + '\' +
TableNameList.Strings[TableNum] + '.CSV';
Caption := 'Saving "' + ExtractFileName(FileName) + '"';
ADOTable1.TableName := TableNameList.Strings[TableNum];
ADOTable1.Active := true;
OutFileList.Clear;
ADOTable1.First;
while not ADOTable1.Eof do
begin
RecString := '';
for FieldNum := 0 to ADOTable1.FieldCount - 1 do
begin
VT := VarType(ADOTable1.Fields[FieldNum].Value);
case VT of
// just write the field if not a string
vtInteger, vtExtended, vtCurrency, vtInt64:
RecString := RecString + ADOTable1.Fields[FieldNum].AsString
else
// it IS a string so put quotes around it
RecString := RecString + '"' +
ADOTable1.Fields[FieldNum].AsString + '"';
end; { case }
// if not the last field then use a field separator
if FieldNum < (ADOTable1.FieldCount - 1) then
RecString := RecString + ',';
end; { for FieldNum }
OutFileList.Add(RecString);
ADOTable1.Next;
end; { while }
OutFileList.SaveToFile(FileName);
InfoStr := InfoStr + FileName + #13;
ADOTable1.Active := false;
end; { for TableNum }
TableNameList.Free;
OutFileList.Free;
Caption := 'Done';
ShowMessage(InfoStr);
end;
procedure TMainForm.Button1Click(Sender: TObject);
const
ConnStrA = 'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=';
ConnStrC = ';Persist Security Info=False';
ProvStr = 'Microsoft.Jet.OLEDB.4.0';
begin
OpenDialog1.InitialDir := ExtractFileDir(ParamStr(0));
if OpenDialog1.Execute then
try
ADOConnection1.ConnectionString :=
ConnStrA + OpenDialog1.FileName + ConnStrC;
ADOConnection1.Provider := ProvStr;
ADOConnection1.Connected := true;
ADOTable1.Connection := ADOConnection1;
SaveAllTablesToCSV(OpenDialog1.FileName);
except
ShowMessage('Could not Connect to ' + #13 +
'"' + OpenDialog1.FileName + '"');
Close;
end;
end;
Взято с
Delphi Knowledge BaseКак экстрагировать аудиодорожку из AVI файла?
Как экстрагировать аудиодорожку из AVI файла?
uses
{...}, vfw;
var
abort: Boolean;
{$R *.DFM}
{Vielen Dank an Jailbird, der einen groЯen Teil dieses Codes entwickelt hat
Special thanks to Jailbird, who developed a big part of this Code}
{Bitte zuerst die vfw.pas downloaden
Please download th vfw.pas first }
{Die 'SaveCallback' Funktion erlaubt es dem Benutzer den
aktuellen Prozess Status zu erfahren und den Speichervorgang
vorzeitig abzubrechen. Diese Funktion muss NICHT vom Benutzer
aufgerufen werden.
The 'SaveCallback' function allows the user to get the
process status and abort the save progress. This function
needn't to call by the user.}
function SaveCallback(nPercent: Int): Bool; pascal;
begin
Application.ProcessMessages;
Form1.Progressbar1.Position := nPercent; //Speicher Status in Prozent
//Save Status in Percent
if abort = True then
Result := True //Wenn die Funktion "True" zurьckgibt, wird der Speichervorgang fortgesetzt.
else //If then function returns "True", the Process will continue
Result := False; //Gibt sie "False" zurьck wird der Vorgang abgebrochen
end; //If it returns "False" the process will abort
{Die folgende Funktion erwartet zwei Parameter:
Inputfile: PChar
Geben Sie hier die die AVI Datei an aus welche Sie
die Audiospur extrahieren mцchten.
Outputfile: PChar
Geben Sie einen Pfad + Dateinamen einer WAVE Datei an.
In diese Datei wird die AudioSpur gespeichert.
HINWEIS:
Geben Sie nur eine WAVE Datei als Ausgabedatei an wenn
die Audiodaten in der AVI Datei unkomprimiert (als PCM WAVE)
vorliegen.
####################################################
The following function needs two parameters:
InputFile: PChar
Enter a Dir + Filename of a AVI File.
OutputFile: PChar
Enter a Dir + Filename of a WAVE File where do you want to
put the audiodata of the movie.
TIP:
Enter jus a Filename of a WAVE File if the audiodata of the
movie is in uncompressed PCM Format.
###########################################################
WICHTIG:
Stellen Sie vor dem aufrufen der Funktion 'ExtractAVISound' sicher
das die Eingabedatei (Inputfile) ьber eine AudioSpur verfьgt.
IMPORTANT:
Before calling the 'ExtractAVISound' function be sure that the
Inputfile has a audiotrace.
}
function TForm1.ExtractAVISound(InputFile, Outputfile: PChar): Boolean;
var
PFile: IAviFile;
PAvi: IAviStream;
plpOptions: PAviCompressOptions;
begin
Abort := False;
if Fileexists(StrPas(Outputfile)) then
begin
case MessageDlg('Ausgabedatei existiert bereits. Ьberschreiben?',
mtWarning, [mbYes, mbNo], 0) of
mrYes:
begin
DeleteFile(StrPas(Outputfile)); //Wichtig, da die Funktion sonst nur so viel der
end; //Datei ьberschreibt wie gebraucht wird.
//Important because the function overwrite just
//the part of the file which is needed.
mrNo:
begin
Exit;
end;
end;
end;
try //Initialisiert die API
AviFileInit; //Init the API
if AviFileOpen(PFile, Inputfile, 0, nil) <> 0 then //Цffnet eine AVI Datei
begin //Opens a AVI File
MessageDlg('Fehler beim laden des Videos.
Mцglicherweise wird die Datei von einem anderen Prozess verwendet.'
+ #13#10 +
'SchlieЯen Sie alle in Frage kommenden Anwendungen und versuchen Sie es erneut.',
mtError, [mbOK], 0);
Result := False;
Exit;
end;
if AviFileGetStream(PFile, PAvi, StreamTypeAudio, 0) <> 0 then
begin
MessageDlg(
'Fehler beim laden des AudioStreams. Bitte ьberprьfen Sie, ob dieses Video ьber einen AudioStream verfьgt.',
mtError, [mbOK], 0);
AviFileExit;
Result := False;
Exit;
end;
//Speichert den AudioStream
//Saves the AudioStream
if AviSaveV(Outputfile, nil, @SaveCallback, 1, PAvi, plpOptions) <> 0 then
begin
MessageDlg('Fehler beim Speichern des AudioStreams oder Sie haben den Speichervorgang abgebrochen.',
mtError, [mbOK], 0);
AviStreamRelease(PAvi);
AviFileExit;
Result := False;
Exit;
end;
finally
AviStreamRelease(PAvi);
AviFileExit;
end;
Result := True; //'TRUE' zurьckgeben wenn alles geklappt hat
//return 'TRUE' if all right
end;
//Beispiel zu aufrufen der Funktion:
//Example how to call the function:
procedure TForm1.Button1Click(Sender: TObject);
begin
if ExtractAVISound(PChar('D:\test.avi'), PChar('D:\test.wav')) = True then
ShowMessage('Audiospur erfolgreich gespeichert!'); // Audio sucessfully saved
else
ShowMessage('Fehler beim Speichern der Audiospur.'); // Error while saving...
end;
Взято с сайта
Как экстрагировать фрейм из AVI?
Как экстрагировать фрейм из AVI?
uses
VfW { from download };
function GrabAVIFrame(avifn: string; iFrameNumber: Integer; ToFileName: TFileName): Boolean;
var
Error: Integer;
pFile: PAVIFile;
AVIStream: PAVIStream;
gapgf: PGETFRAME;
lpbi: PBITMAPINFOHEADER;
bits: PChar;
hBmp: HBITMAP;
AviInfo: TAVIFILEINFOW;
sError: string;
TmpBmp: TBitmap;
DC_Handle: HDC;
begin
Result := False;
// Initialize the AVIFile library.
AVIFileInit;
// The AVIFileOpen function opens an AVI file
Error := AVIFileOpen(pFile, PChar(avifn), 0, nil);
if Error <> 0 then
begin
AVIFileExit;
case Error of
AVIERR_BADFORMAT: sError := 'The file couldnot be read';
AVIERR_MEMORY: sError := 'The file could not be opened because of insufficient memory.';
AVIERR_FILEREAD: sError := 'A disk error occurred while reading the file.';
AVIERR_FILEOPEN: sError := 'A disk error occurred while opening the file.';
end;
ShowMessage(sError);
Exit;
end;
// AVIFileInfo obtains information about an AVI file
if AVIFileInfo(pFile, @AVIINFO, SizeOf(AVIINFO)) <> AVIERR_OK then
begin
// Clean up and exit
AVIFileRelease(pFile);
AVIFileExit;
Exit;
end;
// Show some information about the AVI
Form1.Memo1.Lines.Add('AVI Width : ' + IntToStr(AVIINFO.dwWidth));
Form1.Memo1.Lines.Add('AVI Height : ' + IntToStr(AVIINFO.dwHeight));
Form1.Memo1.Lines.Add('AVI Length : ' + IntToStr(AVIINFO.dwLength));
// Open a Stream from the file
Error := AVIFileGetStream(pFile, AVIStream, streamtypeVIDEO, 0);
if Error <> AVIERR_OK then
begin
// Clean up and exit
AVIFileRelease(pFile);
AVIFileExit;
Exit;
end;
// Prepares to decompress video frames
gapgf := AVIStreamGetFrameOpen(AVIStream, nil);
if gapgf = nil then
begin
AVIStreamRelease(AVIStream);
AVIFileRelease(pFile);
AVIFileExit;
Exit;
end;
// Read current Frame
// AVIStreamGetFrame Returns the address of a decompressed video frame
lpbi := AVIStreamGetFrame(gapgf, iFrameNumber);
if lpbi = nil then
begin
AVIStreamGetFrameClose(gapgf);
AVIStreamRelease(AVIStream);
AVIFileRelease(pFile);
AVIFileExit;
Exit;
end;
// Show number of frames:
Form1.Memo1.Lines.Add(Format('Framstart: %d FrameEnd: %d',
[AVIStreamStart(AVIStream), AVIStreamEnd(AVIStream)]));
TmpBmp := TBitmap.Create;
try
TmpBmp.Height := lpbi.biHeight;
TmpBmp.Width := lpbi.biWidth;
bits := Pointer(Integer(lpbi) + SizeOf(TBITMAPINFOHEADER));
DC_Handle := CreateDC('Display', nil, nil, nil);
try
hBmp := CreateDIBitmap(DC_Handle, // handle of device context
lpbi^, // address of bitmap size and format data
CBM_INIT, // initialization flag
bits, // address of initialization data
PBITMAPINFO(lpbi)^, // address of bitmap color-format data
DIB_RGB_COLORS); // color-data usage
finally
DeleteDC(DC_Handle);
end;
TmpBmp.Handle := hBmp;
AVIStreamGetFrameClose(gapgf);
AVIStreamRelease(AVIStream);
AVIFileRelease(pfile);
AVIFileExit;
try
TmpBmp.SaveToFile(ToFileName);
Result := True;
except
end;
finally
TmpBmp.Free;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
// Extract Frame 3 from AVI file
GrabAVIFrame('C:\Test.avi', 3, 'c:\avifram.bmp');
end;
Взято с сайта
Как эмулировать нажатия клавиш в другой программе?
Как эмулировать нажатия клавиш в другой программе?
Как эмулировать нажатия клавиш в другой программе
http://delfaq.wallst.ru/faq/emul.html
Этот модуль является почти полным аналогом мотоду SendKeys из VB.
(Автор: Ken Henderson, email:khen@compuserve.com)
================================================================
(*
SendKeys routine for 32-bit Delphi.
Written by Ken Henderson
Copyright (c) 1995 Ken Henderson email:khen@compuserve.com
This unit includes two routines that simulate popular Visual Basic
routines: Sendkeys and AppActivate. SendKeys takes a PChar
as its first parameter and a boolean as its second, like so:
SendKeys('KeyString', Wait);
where KeyString is a string of key names and modifiers that you want
to send to the current input focus and Wait is a boolean variable or value
that indicates whether SendKeys should wait for each key message to be
processed before proceeding. See the table below for more information.
AppActivate also takes a PChar as its only parameter, like so:
AppActivate('WindowName');
where WindowName is the name of the window that you want to make the
current input focus.
SendKeys supports the Visual Basic SendKeys syntax, as documented below.
Supported modifiers:
+ = Shift
^ = Control
% = Alt
Surround sequences of characters or key names with parentheses in order to
modify them as a group. For example, '+abc' shifts only 'a', while '+(abc)' shifts
all three characters.
Supported special characters
~ = Enter
( = Begin modifier group (see above)
) = End modifier group (see above)
{ = Begin key name text (see below)
} = End key name text (see below)
Supported characters:
Any character that can be typed is supported. Surround the modifier keys
listed above with braces in order to send as normal text.
Supported key names (surround these with braces):
BKSP, BS, BACKSPACE
BREAK
CAPSLOCK
CLEAR
DEL
DELETE
DOWN
END
ENTER
ESC
ESCAPE
F1
F2
F3
F4
F5
F6
F7
F8
F9
F10
F11
F12
F13
F14
F15
F16
HELP
HOME
INS
LEFT
NUMLOCK
PGDN
PGUP
PRTSC
RIGHT
SCROLLLOCK
TAB
UP
Follow the keyname with a space and a number to send the specified key a
given number of times (e.g., {left 6}).
*)
unit sndkey32;
interface
Uses SysUtils, Windows, Messages;
function SendKeys(SendKeysString : PChar; Wait : Boolean) : Boolean;
function AppActivate(WindowName : PChar) : boolean;
{Buffer for working with PChar's}
const
WorkBufLen = 40;
var
WorkBuf : array[0..WorkBufLen] of Char;
implementation
type
THKeys = array[0..pred(MaxLongInt)] of byte;
var
AllocationSize : integer;
(*
Converts a string of characters and key names to keyboard events and
passes them to Windows.
Example syntax:
SendKeys('abc123{left}{left}{left}def{end}456{left 6}ghi{end}789', True);
*)
function SendKeys(SendKeysString : PChar; Wait : Boolean) : Boolean;
type
WBytes = array[0..pred(SizeOf(Word))] of Byte;
TSendKey = record
Name : ShortString;
VKey : Byte;
end;
const
{Array of keys that SendKeys recognizes.
if you add to this list, you must be sure to keep it sorted alphabetically
by Name because a binary search routine is used to scan it.}
MaxSendKeyRecs = 41;
SendKeyRecs : array[1..MaxSendKeyRecs] of TSendKey =
(
(Name:'BKSP'; VKey:VK_BACK),
(Name:'BS'; VKey:VK_BACK),
(Name:'BACKSPACE'; VKey:VK_BACK),
(Name:'BREAK'; VKey:VK_CANCEL),
(Name:'CAPSLOCK'; VKey:VK_CAPITAL),
(Name:'CLEAR'; VKey:VK_CLEAR),
(Name:'DEL'; VKey:VK_DELETE),
(Name:'DELETE'; VKey:VK_DELETE),
(Name:'DOWN'; VKey:VK_DOWN),
(Name:'END'; VKey:VK_END),
(Name:'ENTER'; VKey:VK_RETURN),
(Name:'ESC'; VKey:VK_ESCAPE),
(Name:'ESCAPE'; VKey:VK_ESCAPE),
(Name:'F1'; VKey:VK_F1),
(Name:'F10'; VKey:VK_F10),
(Name:'F11'; VKey:VK_F11),
(Name:'F12'; VKey:VK_F12),
(Name:'F13'; VKey:VK_F13),
(Name:'F14'; VKey:VK_F14),
(Name:'F15'; VKey:VK_F15),
(Name:'F16'; VKey:VK_F16),
(Name:'F2'; VKey:VK_F2),
(Name:'F3'; VKey:VK_F3),
(Name:'F4'; VKey:VK_F4),
(Name:'F5'; VKey:VK_F5),
(Name:'F6'; VKey:VK_F6),
(Name:'F7'; VKey:VK_F7),
(Name:'F8'; VKey:VK_F8),
(Name:'F9'; VKey:VK_F9),
(Name:'HELP'; VKey:VK_HELP),
(Name:'HOME'; VKey:VK_HOME),
(Name:'INS'; VKey:VK_INSERT),
(Name:'LEFT'; VKey:VK_LEFT),
(Name:'NUMLOCK'; VKey:VK_NUMLOCK),
(Name:'PGDN'; VKey:VK_NEXT),
(Name:'PGUP'; VKey:VK_PRIOR),
(Name:'PRTSC'; VKey:VK_PRINT),
(Name:'RIGHT'; VKey:VK_RIGHT),
(Name:'SCROLLLOCK'; VKey:VK_SCROLL),
(Name:'TAB'; VKey:VK_TAB),
(Name:'UP'; VKey:VK_UP)
);
{Extra VK constants missing from Delphi's Windows API interface}
VK_NULL=0;
VK_SemiColon=186;
VK_Equal=187;
VK_Comma=188;
VK_Minus=189;
VK_Period=190;
VK_Slash=191;
VK_BackQuote=192;
VK_LeftBracket=219;
VK_BackSlash=220;
VK_RightBracket=221;
VK_Quote=222;
VK_Last=VK_Quote;
ExtendedVKeys : set of byte =
[VK_Up,
VK_Down,
VK_Left,
VK_Right,
VK_Home,
VK_End,
VK_Prior, {PgUp}
VK_Next, {PgDn}
VK_Insert,
VK_Delete];
const
INVALIDKEY = $FFFF;
VKKEYSCANSHIFTON = $01;
VKKEYSCANCTRLON = $02;
VKKEYSCANALTON = $04;
UNITNAME = 'SendKeys';
var
UsingParens, ShiftDown, ControlDown, AltDown, FoundClose : Boolean;
PosSpace : Byte;
I, L : Integer;
NumTimes, MKey : Word;
KeyString : String[20];
procedure DisplayMessage(Message : PChar);
begin
MessageBox(0,Message,UNITNAME,0);
end;
function BitSet(BitTable, BitMask : Byte) : Boolean;
begin
Result:=ByteBool(BitTable and BitMask);
end;
procedure SetBit(var BitTable : Byte; BitMask : Byte);
begin
BitTable:=BitTable or Bitmask;
end;
procedure KeyboardEvent(VKey, ScanCode : Byte; Flags : Longint);
var
KeyboardMsg : TMsg;
begin
keybd_event(VKey, ScanCode, Flags,0);
if (Wait) then While (PeekMessage(KeyboardMsg,0,WM_KEYFIRST, WM_KEYLAST, PM_REMOVE)) do begin
TranslateMessage(KeyboardMsg);
DispatchMessage(KeyboardMsg);
end;
end;
procedure SendKeyDown(VKey: Byte; NumTimes : Word; GenUpMsg : Boolean);
var
Cnt : Word;
ScanCode : Byte;
NumState : Boolean;
KeyBoardState : TKeyboardState;
begin
if (VKey=VK_NUMLOCK) then begin
NumState:=ByteBool(GetKeyState(VK_NUMLOCK) and 1);
GetKeyBoardState(KeyBoardState);
if NumState then KeyBoardState[VK_NUMLOCK]:=(KeyBoardState[VK_NUMLOCK] and not 1)
else KeyBoardState[VK_NUMLOCK]:=(KeyBoardState[VK_NUMLOCK] or 1);
SetKeyBoardState(KeyBoardState);
exit;
end;
ScanCode:=Lo(MapVirtualKey(VKey,0));
For Cnt:=1 to NumTimes do
if (VKey in ExtendedVKeys)then begin
KeyboardEvent(VKey, ScanCode, KEYEVENTF_EXTENDEDKEY);
if (GenUpMsg) then
KeyboardEvent(VKey, ScanCode, KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP)
end else begin
KeyboardEvent(VKey, ScanCode, 0);
if (GenUpMsg) then KeyboardEvent(VKey, ScanCode, KEYEVENTF_KEYUP);
end;
end;
procedure SendKeyUp(VKey: Byte);
var
ScanCode : Byte;
begin
ScanCode:=Lo(MapVirtualKey(VKey,0));
if (VKey in ExtendedVKeys)then
KeyboardEvent(VKey, ScanCode, KEYEVENTF_EXTENDEDKEY and KEYEVENTF_KEYUP)
else KeyboardEvent(VKey, ScanCode, KEYEVENTF_KEYUP);
end;
procedure SendKey(MKey: Word; NumTimes : Word; GenDownMsg : Boolean);
begin
if (BitSet(Hi(MKey),VKKEYSCANSHIFTON)) then SendKeyDown(VK_SHIFT,1,False);
if (BitSet(Hi(MKey),VKKEYSCANCTRLON)) then SendKeyDown(VK_CONTROL,1,False);
if (BitSet(Hi(MKey),VKKEYSCANALTON)) then SendKeyDown(VK_MENU,1,False);
SendKeyDown(Lo(MKey), NumTimes, GenDownMsg);
if (BitSet(Hi(MKey),VKKEYSCANSHIFTON)) then SendKeyUp(VK_SHIFT);
if (BitSet(Hi(MKey),VKKEYSCANCTRLON)) then SendKeyUp(VK_CONTROL);
if (BitSet(Hi(MKey),VKKEYSCANALTON)) then SendKeyUp(VK_MENU);
end;
{Implements a simple binary search to locate special key name strings}
function StringToVKey(KeyString : ShortString) : Word;
var
Found, Collided : Boolean;
Bottom, Top, Middle : Byte;
begin
Result:=INVALIDKEY;
Bottom:=1;
Top:=MaxSendKeyRecs;
Found:=false;
Middle:=(Bottom+Top) div 2;
Repeat
Collided:=((Bottom=Middle) or (Top=Middle));
if (KeyString=SendKeyRecs[Middle].Name) then begin
Found:=true;
Result:=SendKeyRecs[Middle].VKey;
if (KeyString>SendKeyRecs[Middle].Name) then Bottom:=Middle
else Top:=Middle;
Middle:=(Succ(Bottom+Top)) div 2;
end;
Until (Found or Collided);
if (Result=INVALIDKEY) then DisplayMessage('Invalid Key Name');
end;
procedure PopUpShiftKeys;
begin
if (not UsingParens) then begin
if ShiftDown then SendKeyUp(VK_SHIFT);
if ControlDown then SendKeyUp(VK_CONTROL);
if AltDown then SendKeyUp(VK_MENU);
ShiftDown:=false;
ControlDown:=false;
AltDown:=false;
end;
end;
begin
AllocationSize:=MaxInt;
Result:=false;
UsingParens:=false;
ShiftDown:=false;
ControlDown:=false;
AltDown:=false;
I:=0;
L:=StrLen(SendKeysString);
if (L>AllocationSize) then L:=AllocationSize;
if (L=0) then Exit;
While (I
case SendKeysString[I] of
'(' : begin
UsingParens:=true;
Inc(I);
end;
')' : begin
UsingParens:=false;
PopUpShiftKeys;
Inc(I);
end;
'%' : begin
AltDown:=true;
SendKeyDown(VK_MENU,1,False);
Inc(I);
end;
'+' : begin
ShiftDown:=true;
SendKeyDown(VK_SHIFT,1,False);
Inc(I);
end;
'^' : begin
ControlDown:=true;
SendKeyDown(VK_CONTROL,1,False);
Inc(I);
end;
'{' : begin
NumTimes:=1;
if (SendKeysString[Succ(I)]='{') then begin
MKey:=VK_LEFTBRACKET;
SetBit(Wbytes(MKey)[1],VKKEYSCANSHIFTON);
SendKey(MKey,1,True);
PopUpShiftKeys;
Inc(I,3);
Continue;
end;
KeyString:='';
FoundClose:=false;
While (I<=L) do begin
Inc(I);
if (SendKeysString[I]='}') then begin
FoundClose:=true;
Inc(I);
Break;
end;
KeyString:=KeyString+Upcase(SendKeysString[I]);
end;
if (Not FoundClose) then begin
DisplayMessage('No Close');
Exit;
end;
if (SendKeysString[I]='}') then begin
MKey:=VK_RIGHTBRACKET;
SetBit(Wbytes(MKey)[1],VKKEYSCANSHIFTON);
SendKey(MKey,1,True);
PopUpShiftKeys;
Inc(I);
Continue;
end;
PosSpace:=Pos(' ',KeyString);
if (PosSpace<>0) then begin
NumTimes:=StrToInt(Copy(KeyString,Succ(PosSpace),Length(KeyString)-PosSpace));
KeyString:=Copy(KeyString,1,Pred(PosSpace));
end;
if (Length(KeyString)=1) then MKey:=vkKeyScan(KeyString[1])
else MKey:=StringToVKey(KeyString);
if (MKey<>INVALIDKEY) then begin
SendKey(MKey,NumTimes,True);
PopUpShiftKeys;
Continue;
end;
end;
'~' : begin
SendKeyDown(VK_RETURN,1,True);
PopUpShiftKeys;
Inc(I);
end;
else begin
MKey:=vkKeyScan(SendKeysString[I]);
if (MKey<>INVALIDKEY) then begin
SendKey(MKey,1,True);
PopUpShiftKeys;
end else DisplayMessage('Invalid KeyName');
Inc(I);
end;
end;
end;
Result:=true;
PopUpShiftKeys;
end;
{AppActivate
This is used to set the current input focus to a given window using its
name. This is especially useful for ensuring a window is active before
sending it input messages using the SendKeys function. You can specify
a window's name in its entirety, or only portion of it, beginning from
the left.
}
var
WindowHandle : HWND;
function EnumWindowsProc(WHandle: HWND; lParam: LPARAM): BOOL; export; stdcall;
const
MAX_WINDOW_NAME_LEN = 80;
var
WindowName : array[0..MAX_WINDOW_NAME_LEN] of char;
begin
{Can't test GetWindowText's return value since some windows don't have a title}
GetWindowText(WHandle,WindowName,MAX_WINDOW_NAME_LEN);
Result := (StrLIComp(WindowName,PChar(lParam), StrLen(PChar(lParam))) <> 0);
if (not Result) then WindowHandle:=WHandle;
end;
function AppActivate(WindowName : PChar) : boolean;
begin
try
Result:=true;
WindowHandle:=FindWindow(nil,WindowName);
if (WindowHandle=0) then EnumWindows(@EnumWindowsProc,Intege (PChar(WindowName)));
if (WindowHandle<>0) then begin
SendMessage(WindowHandle, WM_SYSCOMMAND, SC_HOTKEY, WindowHandle);
SendMessage(WindowHandle, WM_SYSCOMMAND, SC_RESTORE, WindowHandle);
end else Result:=false;
except
on Exception do Result:=false;
end;
end;
end.
Взято с сайта
Как качественно увеличить изображение при помощи билинейной интерполяции
Как качественно увеличить изображение при помощи билинейной интерполяции
При увеличении изображения нужно находить цвет точек, находящимися между
точками исходного изображения. Функция CopyRect, встроенная в Delphi берет
для этого цвет ближайшей точки. Увеличенное изображение получается некрасивым.
Чтобы избежать этого, используют интерполяцию.
Существует несколько видов интерполяции изображения. Наиболее простой из них - билинейный.
Изображение рассматривается как поверхность, цвет - третье измерение.
Если изображение цветное, то интерполяция проводится отдельно для трех цветов.
Для каждой точки нового изображения с координатами (xo,yo)
нужно найти четыре ближайшие точки исходного изображения.
Эти точки образуют квадрат. Через две верхние точки проводится прямая f1(x),
через две нижние - f2(x). Дальше находятся координаты для точек f1(xo) и f2(xo),
через которые проводится третья прямая f3(y). Цвет искомой точки - это f3(yo).
Этот алгоритм хорошо работает при целых или больших коэффициентах увеличения.
Но резкие границы размываются. Для уменьшения изображения этот алгоритм также не подходит.
Эта программа при нажатии на Button1 увеличивает часть изображения на экране,
а при нажатии на Button2 увеличивает открытое изображение.
procedure Interpolate(var bm: TBitMap; dx, dy: single);
var
bm1: TBitMap;
z1, z2: single;
k, k1, k2: single;
x1, y1: integer;
c: array [0..1, 0..1, 0..2] of byte;
res: array [0..2] of byte;
x, y: integer;
xp, yp: integer;
xo, yo: integer;
col: integer;
pix: TColor;
begin
bm1 := TBitMap.Create;
bm1.Width := round(bm.Width * dx);
bm1.Height := round(bm.Height * dy);
for y := 0 to bm1.Height - 1 do begin
for x := 0 to bm1.Width - 1 do begin
xo := trunc(x / dx);
yo := trunc(y / dy);
x1 := round(xo * dx);
y1 := round(yo * dy);
for yp := 0 to 1 do
for xp := 0 to 1 do begin
pix := bm.Canvas.Pixels[xo + xp, yo + yp];
c[xp, yp, 0] := GetRValue(pix);
c[xp, yp, 1] := GetGValue(pix);
c[xp, yp, 2] := GetBValue(pix);
end;
for col := 0 to 2 do begin
k1 := (c[1,0,col] - c[0,0,col]) / dx;
z1 := x * k1 + c[0,0,col] - x1 * k1;
k2 := (c[1,1,col] - c[0,1,col]) / dx;
z2 := x * k2 + c[0,1,col] - x1 * k2;
k := (z2 - z1) / dy;
res[col] := round(y * k + z1 - y1 * k);
end;
bm1.Canvas.Pixels[x,y] := RGB(res[0], res[1], res[2]);
end;
Form1.Caption := IntToStr(round(100 * y / bm1.Height)) + '%';
Application.ProcessMessages;
if Application.Terminated then Exit;
end;
bm := bm1;
end;
const
dx = 5.5;
dy = 5.5;
procedure TForm1.Button1Click(Sender: TObject);
const
w = 50;
h = 50;
var
bm: TBitMap;
can: TCanvas;
begin
bm := TBitMap.Create;
can := TCanvas.Create;
can.Handle := GetDC(0);
bm.Width := w;
bm.Height := h;
bm.Canvas.CopyRect(Bounds(0, 0, w, h), can, Bounds(0, 0, w, h));
ReleaseDC(0, can.Handle);
Interpolate(bm, dx, dy);
Form1.Canvas.Draw(0, 0, bm);
Form1.Caption := 'x: ' + FloatToStr(dx) +
' y: ' + FloatToStr(dy) +
' width: ' + IntToStr(w) +
' height: ' + IntToStr(h);
end;
procedure TForm1.Button2Click(Sender: TObject);
var
bm: TBitMap;
begin
if OpenDialog1.Execute then
bm.LoadFromFile(OpenDialog1.FileName);
Interpolate(bm, dx, dy);
Form1.Canvas.Draw(0, 0, bm);
Form1.Caption := 'x: ' + FloatToStr(dx) +
' y: ' + FloatToStr(dy) +
' width: ' + IntToStr(bm.Width) +
' height: ' + IntToStr(bm.Height);
end;
Эта программа строит заданные графики, используя модуль Recognition.
От констант left и right зависит диапазон x, от YScale зависит масштаб по y, а от k зависит качество прорисовки.
uses Recognition;
procedure TForm1.Button1Click(Sender: TObject);
const
left = -10;
right = 10;
YScale = 50;
k = 10;
var
i: integer;
Num: extended;
s: String;
XScale: single;
col: TColor;
begin
s := Edit1.Text;
preparation(s, ['x']);
XScale := PaintBox1.Width / (right - left);
randomize;
col := RGB(random(100), random(100), random(100));
for i := round(left * XScale * k) to round(right * XScale * k) do
if recogn(ChangeVar(s, 'x', i / XScale / k), Num) then
PaintBox1.Canvas.Pixels[round(i / k - left * XScale),
round(PaintBox1.Height / 2 - Num * YScale)] := col;
end;
Взято с сайта
Как клонировать процесс?
Как клонировать процесс?
{
In Linux it is possible to duplicate a process with fork. In the original
process, fork will return the handle to the duplicated process. The
duplicated process will return zero.
}
program TestFork;
{$APPTYPE CONSOLE}
uses
SysUtils,
Libc;
var
ForkedProcessHandle: __pid_t;
bForked: Boolean;
procedure ForkNow;
begin
bForked := true;
ForkedProcessHandle := fork;
end;
function IsForked: Boolean;
begin
Result := (ForkedProcessHandle = 0) and bForked;
end;
var
Lf: Integer;
begin
sigignore(SIGCHLD);
bForked := false;
WriteLn('do some stuff');
WriteLn('before fork');
ForkNow;
WriteLn('after fork - we have dublicated the process');
if IsForked then begin
WriteLn('do some stuff in forked process (wait 5s)');
for Lf := 0 to 50 do begin
Write('f');
sleep(100);
end;
end else begin
WriteLn('do stuff in original process (wait 10)');
for Lf := 0 to 100 do begin
Write('o');
sleep(100);
end;
end;
WriteLn;
if IsForked then
WriteLn('forked process end')
else
WriteLn('original process end');
end.
{
Output of this demo app:
do some stuff
before fork
after fork - we have dublicated the process
after fork - we have dublicated the process
do some stuff in forked process (wait 5s)
fdo stuff in original process (wait 10)
ooffooffooffooffooffooffooffooffooffooffooffooffooffooffooffooffooffooff
ooffooffooffooffooffooffooffoo
forked process end
ooooooooooooooooooooooooooooooooooooooooooooooooo
original process end
}
Взято с сайта
Как консольное приложение может узнать, что Винды завершаются?
Как консольное приложение может узнать, что Винды завершаются?
Автор: Nomadic
Все процессы получают сигналы CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT и CTRL_SHUTDOWN_EVENT. А делается это (грубо говоря :) так:
BOOLCtrl_Handler( DWORD Ctrl )
{
if( (Ctrl == CTRL_SHUTDOWN_EVENT) (Ctrl == CTRL_LOGOFF_EVENT) )
{
// Вау! Юзер обламывает!
}
else
{
// Тут что-от другое можно творить. А можно и не творить :-)
}
return TRUE;
}
function Ctrl_Handler(Ctrl: Longint): LongBool;
begin
if Ctrl in [CTRL_SHUTDOWN_EVENT, CTRL_LOGOFF_EVENT] then
begin
// Вау, вау
end
else
begin
// Am I creator?
end;
Result := true;
end;
А где-то в программе:
SetConsoleCtrlHandler( Ctrl_Handler, TRUE );
Таких обработчиков можно навесить кучу. Если при обработке какого-то из сообщений обработчик возвращает FALSE, то вызывается следующий обработчик. Можно настроить таких этажерок, что ого-го :-)))
Короче, смотри описание SetConsoleCtrlHandler -- там всё есть.
Взято с
Как конвертировать кодовую страницу?
Как конвертировать кодовую страницу?
All Systems (Win 95+ and WinNT4+) with MS Internet Explorer 4 and newer have a library named mlang.dll in the Winnt\System32 directory. Usually you can tell Delphi to simply import these COM Libraries. This one however, Delphi did not. I started to convert the "most wanted" interface for myself. The results I present you here.
First I give you the code for the conversion unit, that allows you simply convert any text from code page interpretation into another one. Following I will shortly discuss the code and give you a sample of how to use it.
uCodePageConverter
{** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Unit Name : uCodePageConverter
* Autor : Daniel Wischnewski
* Copyright : Copyright © 2002 by gate(n)etwork. All Right Reserved.
* Urheber : Daniel Wischnewski
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
unit uCodePageConverter;
interface
uses
Windows;
const
IID_MLangConvertCharset: TGUID = '{D66D6F98-CDAA-11D0-B822-00C04FC9B31F}';
CLASS_MLangConvertCharset: TGUID = '{D66D6F99-CDAA-11D0-B822-00C04FC9B31F}';
type
tagMLCONVCHARF = DWORD;
const
MLCONVCHARF_AUTODETECT: tagMLCONVCHARF = 1;
MLCONVCHARF_ENTITIZE: tagMLCONVCHARF = 2;
type
tagCODEPAGE = UINT;
const
CODEPAGE_Thai: tagCODEPAGE = 0874;
CODEPAGE_Japanese: tagCODEPAGE = 0932;
CODEPAGE_Chinese_PRC: tagCODEPAGE = 0936;
CODEPAGE_Korean: tagCODEPAGE = 0949;
CODEPAGE_Chinese_Taiwan: tagCODEPAGE = 0950;
CODEPAGE_UniCode: tagCODEPAGE = 1200;
CODEPAGE_Windows_31_EastEurope: tagCODEPAGE = 1250;
CODEPAGE_Windows_31_Cyrillic: tagCODEPAGE = 1251;
CODEPAGE_Windows_31_Latin1: tagCODEPAGE = 1252;
CODEPAGE_Windows_31_Greek: tagCODEPAGE = 1253;
CODEPAGE_Windows_31_Turkish: tagCODEPAGE = 1254;
CODEPAGE_Hebrew: tagCODEPAGE = 1255;
CODEPAGE_Arabic: tagCODEPAGE = 1256;
CODEPAGE_Baltic: tagCODEPAGE = 1257;
type
IMLangConvertCharset = interface
['{D66D6F98-CDAA-11D0-B822-00C04FC9B31F}']
function Initialize(
uiSrcCodePage: tagCODEPAGE; uiDstCodePage: tagCODEPAGE;
dwProperty: tagMLCONVCHARF
): HResult; stdcall;
function GetSourceCodePage(
out puiSrcCodePage: tagCODEPAGE
): HResult; stdcall;
function GetDestinationCodePage(
out puiDstCodePage: tagCODEPAGE
): HResult; stdcall;
function GetProperty(out pdwProperty: tagMLCONVCHARF): HResult; stdcall;
function DoConversion(
pSrcStr: PChar; pcSrcSize: PUINT; pDstStr: PChar; pcDstSize: PUINT
): HResult; stdcall;
function DoConversionToUnicode(
pSrcStr: PChar; pcSrcSize: PUINT; pDstStr: PWChar; pcDstSize: PUINT
): HResult; stdcall;
function DoConversionFromUnicode(
pSrcStr: PWChar; pcSrcSize: PUINT; pDstStr: PChar; pcDstSize: PUINT
): HResult; stdcall;
end;
CoMLangConvertCharset = class
class function Create: IMLangConvertCharset;
class function CreateRemote(const MachineName: string): IMLangConvertCharset;
end;
implementation
uses
ComObj;
{ CoMLangConvertCharset }
class function CoMLangConvertCharset.Create: IMLangConvertCharset;
begin
Result := CreateComObject(CLASS_MLangConvertCharset) as IMLangConvertCharset;
end;
class function CoMLangConvertCharset.CreateRemote(
const MachineName: string
): IMLangConvertCharset;
begin
Result := CreateRemoteComObject(
MachineName, CLASS_MLangConvertCharset
) as IMLangConvertCharset;
end;
end.
As you can see, I did translate only one of the many interfaces, however this one is the most efficient (according to Microsoft) and will do the job. Further I added some constants to simplify the task of finding the most important values.
When using this unit to do any code page conersions you must not forget, that the both code pages (source and destination) must be installed and supported on the computer that does the translation. OIn the computer that is going to show the result only the destination code page must be installed and supported.
To test the unit simple create a form with a memo and a button. Add the following code to the buttons OnClick event. (Do not forget to add the conversion unit to the uses clause!)
SAMPLE
procedure TForm1.Button1Click(Sender: TObject);
var
Conv: IMLangConvertCharset;
Source: PWChar;
Dest: PChar;
SourceSize, DestSize: UINT;
begin
// connect to MS multi-language lib
Conv := CoMLangConvertCharset.Create;
// initialize UniCode Translation to Japanese
Conv.Initialize(CODEPAGE_UniCode, CODEPAGE_Japanese, MLCONVCHARF_ENTITIZE);
// load source (from memo)
Source := PWChar(WideString(Memo1.Text));
SourceSize := Succ(Length(Memo1.Text));
// prepare destination
DestSize := 0;
// lets calculate size needed
Conv.DoConversionFromUnicode(Source, @SourceSize, nil, @DestSize);
// reserve memory
GetMem(Dest, DestSize);
try
// convert
Conv.DoConversionFromUnicode(Source, @SourceSize, Dest, @DestSize);
// show
Memo1.Text := Dest;
finally
// free memory
FreeMem(Dest);
end;
end;
Взято с
Delphi Knowledge BaseКак конвертировать RFC дату и обратно?
Как конвертировать RFC дату и обратно?
functionDateTimeToRfcTime(
dt: TDateTime;
iDiff: integer;
blnGMT: boolean = false): string;
{*
Explanation:
iDiff is the local offset to GMT in minutes
if blnGMT then Result is UNC time else local time
e.g. local time zone: ET = GMT - 5hr = -300 minutes
dt is TDateTime of 3 Jan 2001 5:45am
blnGMT = true -> Result = 'Wed, 03 Jan 2001 05:45:00 GMT'
blnGMT = false -> Result = 'Wed, 03 Jan 2001 05:45:00 -0500'
*}
const
Weekday: array[1..7] of string =
('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat');
Month: array[1..12] of string = (
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');
var
iDummy: Word;
iYear: Word;
iMonth: Word;
iDay: Word;
iHour: Word;
iMinute: Word;
iSecond: Word;
strZone: string;
begin
if blnGMT then
begin
dt := dt - iDiff / 1440;
strZone := 'GMT';
end
else
begin
iDiff := (iDiff div 60) * 100 + (iDiff mod 60);
if iDiff < 0 then
strZone := Format('-%.4d', [-iDiff])
else
strZone := Format('+%.4d', [iDiff]);
end;
DecodeDate(dt, iYear, iMonth, iDay);
DecodeTime(dt, iHour, iMinute, iSecond, iDummy);
Result := Format('%s, %.2d %s %4d %.2d:%.2d:%.2d %s', [
Weekday[DayOfWeek(dt)], iDay, Month[iMonth], iYear,
iHour, iMinute, iSecond, strZone]);
end;
function RfcTimeToDateTime(
strTime: string;
blnGMT: boolean = true): TDateTime;
{*
Explanation:
if blnGMT then Result is UNC time else local time
e.g. local time zone: ET = GMT - 5hr = -0500
strTime = 'Wed, 03 Jan 2001 05:45:00 -0500'
blnGMT = true -> FormatDateTime('...', Result) = '03.01.2001 10:45:00'
blnGMT = false -> FormatDateTime('...', Result) = '03.01.2001 05:45:00'
*}
const
wd = 'sun#mon#tue#wed#thu#fri#sat';
month = 'janfebmaraprmayjunjulaugsepoctnovdec';
var
s: string;
dd: Word;
mm: Word;
yy: Word;
hh: Word;
nn: Word;
ss: Word;
begin
s := LowerCase(Copy(strTime, 1, 3));
if Pos(s, wd) > 0 then
Delete(strTime, 1, Pos(' ', strTime));
s := Trim(Copy(strTime, 1, Pos(' ', strTime)));
Delete(strTime, 1, Length(s) + 1);
dd := StrToIntDef(s, 0);
s := LowerCase(Copy(strTime, 1, 3));
Delete(strTime, 1, 4);
mm := (Pos(s, month) div 3) + 1;
s := Copy(strTime, 1, 4);
Delete(strTime, 1, 5);
yy := StrToIntDef(s, 0);
Result := EncodeDate(yy, mm, dd);
s := strTime[1] + strTime[2];
hh := StrToIntDef(strTime[1] + strTime[2], 0);
nn := StrToIntDef(strTime[4] + strTime[5], 0);
ss := StrToIntDef(strTime[7] + strTime[8], 0);
Delete(strTime, 1, 9);
Result := Result + EncodeTime(hh, nn, ss, 0);
if (CompareText(strTime, 'gmt') <> 0) and blnGMT then
begin
hh := StrToIntDef(strTime[2] + strTime[3], 0);
nn := StrToIntDef(strTime[4] + strTime[5], 0);
if strTime[1] = '+' then
Result := Result - EncodeTime(hh, nn, 0, 0)
else
Result := Result + EncodeTime(hh, nn, 0, 0);
end;
end;
Взято с
Delphi Knowledge Basefunction RFC1123ToDateTime(Date: string): TDateTime;
var
day, month, year: Integer;
strMonth: string;
Hour, Minute, Second: Integer;
begin
try
day := StrToInt(Copy(Date, 6, 2));
strMonth := Copy(Date, 9, 3);
if strMonth = 'Jan' then month := 1
else if strMonth = 'Feb' then month := 2
else if strMonth = 'Mar' then month := 3
else if strMonth = 'Apr' then month := 4
else if strMonth = 'May' then month := 5
else if strMonth = 'Jun' then month := 6
else if strMonth = 'Jul' then month := 7
else if strMonth = 'Aug' then month := 8
else if strMonth = 'Sep' then month := 9
else if strMonth = 'Oct' then month := 10
else if strMonth = 'Nov' then month := 11
else if strMonth = 'Dec' then month := 12;
year := StrToInt(Copy(Date, 13, 4));
hour := StrToInt(Copy(Date, 18, 2));
minute := StrToInt(Copy(Date, 21, 2));
second := StrToInt(Copy(Date, 24, 2));
Result := 0;
Result := EncodeTime(hour, minute, second, 0);
Result := Result + EncodeDate(year, month, day);
except
Result := now;
end;
end;
function DateTimeToRFC1123(aDate: TDateTime): string;
const
StrWeekDay: string = 'MonTueWedThuFriSatSun';
StrMonth: string = 'JanFebMarAprMayJunJulAugSepOctNovDec';
var
Year, Month, Day: Word;
Hour, Min, Sec, MSec: Word;
DayOfWeek: Word;
begin
DecodeDate(aDate, Year, Month, Day);
DecodeTime(aDate, Hour, Min, Sec, MSec);
DayOfWeek := ((Trunc(aDate) - 2) mod 7);
Result := Copy(StrWeekDay, 1 + DayOfWeek * 3, 3) + ', ' +
Format('%2.2d %s %4.4d %2.2d:%2.2d:%2.2d',
[Day, Copy(StrMonth, 1 + 3 * (Month - 1), 3),
Year, Hour, Min, Sec]);
end;
Взято с сайта
Как конвертировать RGB в TColor
Как конвертировать RGB в TColor
functionRGBToColor(R,G,B:Byte): TColor;
begin
Result:=B Shl 16 Or
G Shl 8 Or
R;
end;
Взято с Исходников.ru
RGB -> TColor
RGB(r,g,b:byte):tcolor
TColor -> RGB
GetRValue(color:tcolor)
GetGValue(color:tcolor)
GetBValue(color:tcolor)
Автор ответа: Vit
Взято с Vingrad.ru
Как конвертировать виртуальную клавишу в ASCII код?
Как конвертировать виртуальную клавишу в ASCII код?
Получаем символ, соответствующий виртуальной клавише:
function GetCharFromVKey(vkey: Word): string;
var
keystate: TKeyboardState;
retcode: Integer;
begin
Win32Check(GetKeyboardState(keystate));
SetLength(Result, 2);
retcode := ToAscii(vkey,
MapVirtualKey(vkey, 0),
keystate, @Result[1],
0);
case retcode of
0: Result := '';
1: SetLength(Result, 1);
2: ;
else
Result := '';
end;
end;
{
Использование:
procedure TForm1.Edit1KeyDown
(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
ShowMessage(GetCharFromVKey(Key));
end;
}
Взято с Исходников.ru
Как конвертировать WideString в String?
Как конвертировать WideString в String?
{:Converts Unicode string to Ansi string using specified code page.
@param ws Unicode string.
@param codePage Code page to be used in conversion.
@returns Converted ansi string.
}
function WideStringToString(const ws: WideString; codePage: Word): AnsiString;
var
l: integer;
begin
if ws = ' then
Result := '
else
begin
l := WideCharToMultiByte(codePage,
WC_COMPOSITECHECK or WC_DISCARDNS or WC_SEPCHARS or WC_DEFAULTCHAR,
@ws[1], - 1, nil, 0, nil, nil);
SetLength(Result, l - 1);
if l > 1 then
WideCharToMultiByte(codePage,
WC_COMPOSITECHECK or WC_DISCARDNS or WC_SEPCHARS or WC_DEFAULTCHAR,
@ws[1], - 1, @Result[1], l - 1, nil, nil);
end;
end; { WideStringToString }
{:Converts Ansi string to Unicode string using specified code page.
@param s Ansi string.
@param codePage Code page to be used in conversion.
@returns Converted wide string.
}
function StringToWideString(const s: AnsiString; codePage: Word): WideString;
var
l: integer;
begin
if s = ' then
Result := '
else
begin
l := MultiByteToWideChar(codePage, MB_PRECOMPOSED, PChar(@s[1]), - 1, nil, 0);
SetLength(Result, l - 1);
if l > 1 then
MultiByteToWideChar(CodePage, MB_PRECOMPOSED, PChar(@s[1]),
- 1, PWideChar(@Result[1]), l - 1);
end;
end; { StringToWideString }
Взято с сайта
Как копировать и удалять таблицы?
Как копировать и удалять таблицы?
Here is an example of a routine that I use for copying and deleting tables. It uses DB, DBTables, DbiProcs,DbiErrs, and DbiTypes.
You simply provide the directory to copy from, the source table name, the directory to copy to, and the destination table name, and the BDE will copy the entire table, indexes and all to the new file.
The delete function takes the path to delete from and the name of the table to delete, the BDE takes care of deleting all associated files (indexes, etc.).
These procedures have been pulled off a form of mine, and I've edited them to remove some dependencies that existed with that form. They should now be completely stand-alone.
procedureTConvertForm.CopyTable(FromDir, SrcTblName, ToDir, DestTblName: string);
var
DBHandle: HDBIDB;
ResultCode: DBIResult;
Src, Dest, Err: array[0..255] of Char;
SrcTbl, DestTbl: TTable;
begin
SrcTbl := TTable.Create(Application);
DestTbl := TTable.Create(Application);
try
SrcTbl.DatabaseName := FromDir;
SrcTbl.TableName := SrcTblName;
SrcTbl.Open;
DBHandle := SrcTbl.DBHandle;
SrcTbl.Close;
ResultCode := DbiCopyTable(DBHandle, false,
StrPCopy(Src, FromDir + '\' + SrcTblName), nil,
StrPCopy(Dest, ToDir + '\' + DestTblName));
if ResultCode <> DBIERR_NONE then
begin
DbiGetErrorString(ResultCode, Err);
raise EDatabaseError.Create('While copying ' +
FromDir + '\' + SrcTblName + ' to ' +
ToDir + '\' + DestTblName + ', the '
+ ' database engine generated the error '''
+ StrPas(Err) + '''');
end;
finally
SrcTbl.Free;
DestTbl.Free;
end;
end;
procedure TConvertForm.DeleteTable(Dir, TblName: string);
var
DBHandle: HDBIDB;
ResultCode: DBIResult;
tbl, Err: array[0..255] of Char;
SrcTbl, DestTbl: TTable;
begin
SrcTbl := TTable.Create(Application);
try
SrcTbl.DatabaseName := Dir;
SrcTbl.TableName := TblName;
SrcTbl.Open;
DBHandle := SrcTbl.DBHandle;
SrcTbl.Close;
ResultCode := DbiDeleteTable(DBHandle,
StrPCopy(Tbl, Dir + '\' + TblName), nil);
if ResultCode <> DBIERR_NONE then
begin
DbiGetErrorString(ResultCode, Err);
raise EDatabaseError.Create('While deleting ' +
Dir + '\' + TblName + ', the database ' +
'engine generated the error ''' + StrPas(Err) + '''');
end;
finally
SrcTbl.Free;
end;
end;
Взято с
Delphi Knowledge BaseКак копировать и вставлять Bitmap через буфер обмена?
Как копировать и вставлять Bitmap через буфер обмена?
Некоторые функции для копирования и вставки Bitmap-объектов через буфер обмена.
function CopyClipToBuf(DC: HDC; Left, Top, Width, Height: Integer; Rop: LongInt; var CopyDC: HDC; var CopyBitmap: HBitmap): Boolean;
var
TempBitmap: HBitmap;
begin
Result := False;
CopyDC := 0;
CopyBitmap := 0;
if DC <> 0 then
begin
CopyDC := CreateCompatibleDC(DC);
if CopyDC <> 0 then
begin
CopyBitmap := CreateCompatibleBitmap(DC, Width, Height);
if CopyBitmap <> 0 then
begin
TempBitmap := CopyBitmap;
CopyBitmap := SelectObject(CopyDC, CopyBitmap);
Result := BitBlt(CopyDC, 0, 0, Width, Height, DC, Left, Top, Rop);
CopyBitmap := TempBitmap;
end;
end;
end;
end;
function CopyBufToClip(DC: HDC; var CopyDC: HDC; var CopyBitmap: HBitmap;
Left, Top, Width, Height: Integer;
Rop: LongInt; DeleteObjects: Boolean): Boolean;
var
TempBitmap: HBitmap;
begin
Result := False;
if (DC <> 0) and (CopyDC <> 0) and (CopyBitmap <> 0) then
begin
TempBitmap := CopyBitmap;
CopyBitmap := SelectObject(DC, CopyBitmap);
Result := BitBlt(DC, Left, Top, Width, Height, CopyDC, 0, 0, Rop);
CopyBitmap := TempBitmap;
if DeleteObjects then
begin
DeleteDC(CopyDC);
DeleteObject(CopyBitmap);
end;
end;
end;
Как копировать и вставлять TreeNode?
Как копировать и вставлять TreeNode?
var
SL : TStringList;
procedure TForm1.CutBtnClick(Sender: TObject);
var
i, j, StartLevel : integer;
TNSel : TTreeNode;
begin
TNSel := TreeView1.Selected;
if TNSel <> nil then begin
StartLevel := TNSel.Level;
i := TNSel.AbsoluteIndex;
j := i; // note for later deletion
if SL = nil then
SL := TStringList.Create
else
SL.Clear;
SL.AddObject(TNSel.Text, pointer(0));
inc(i);
with TreeView1 do begin
while Items[i].Level > StartLevel do begin
{stop before next sibling to top node\}
SL.AddObject(Items[i].Text, pointer(Items[i].Level - StartLevel));
inc(i);
end; {while Items[i].Level > StartLevel\}
Items[j].Delete;
end; {with TreeView1\}
end; {if TNSel <> nil\}
end;
procedure TForm1.PasteBtnClick(Sender: TObject);
var
i, Level : integer;
TNSel, TN : TTreeNode;
begin
with TreeView1 do begin
TNSel := Selected;
if TNSel <> nil then begin
TN := Items.Insert(TNSel, SL.Strings[0]);
Level := integer(SL.Objects[0]); // should be 0
for i := 1 to SL.Count - 1 do begin
if integer(SL.Objects[i]) < Level then begin
{go up one level\}
TN := TN.Parent;
Level := integer(SL.Objects[i]);
end; {if integer(SL.Objects[i]) < Level\}
if Level = integer(SL.Objects[i]) then
{same level\}
TN := Items.Add(TN, SL.Strings[i])
else begin
{go down one level\}
TN := Items.AddChild(TN, SL.Strings[i]);
Level := integer(SL.Objects[i]);
end; {if Level = integer(SL.Objects[i])\}
end; {for i := 1 to SL.Count - 1\}
end; {if TNSel <> nil\}
end; {with TreeView1\}
end;
Взято с
Как копировать образ экрана в файл
Как копировать образ экрана в файл
На форме у меня стоит TImage (его можно сделать невидимым)
uses JPEG;
...
var i: TJPEGImage;
begin
try
i := TJPEGImage.create;
try
i.CompressionQuality := 100;
image.Width := screen.width;
image.height := screen.height;
DWH := GetDesktopWindow;
GetWindowRect(DWH, DRect);
DescDC := GetDeviceContext(DWH);
Canv.Handle := DescDC;
DRect.Left := 0;
DRect.Top := 0;
DRect.Right := screen.Width;
DRect.Bottom := screen.Height;
Image.Canvas.CopyRect(DRect, Canv, DRect);
i.assign(Image.Picture.Bitmap);
I.SaveToFile('M:\MyFile.jpg');
finally
i.free;
end;
except
end;
Типы использованных переменных:
Dwh : HWND;
DRect: TRect;
DescDC : HDC;
Canv : TCanvas;
Автор ответа: Vit
Взято с Vingrad.ru
Как копировать RTF текст в буффер обмена?
Как копировать RTF текст в буффер обмена?
{
You have to dig into the Rich Text Format if you want to copy text to the
clipboard that has format information embedded. The application you paste
this text into has to understand RTF, or the formatting will not show up.
OK, the first step is to register a clipboard format for RTF, since this is
not a predefined format:
}
Var
CF_RTF : Word;
CF_RTF := RegisterClipboardFormat('Rich Text Format');
{
The format name has to appear as typed above, this is the name used by MS
Word for Windows and similar MS products.
NOTE: The Richedit Unit declares a constant CF_RTF, which is NOT the
clipboard format handle but the string you need to pass to RegisterClipboard
format! So you can place Richedit into your uses clause and change the line
above to
}
CF_RTF := RegisterClipboardFormat(Richedit.CF_RTF);
{
The next step is to build a RTF string with the embedded format information.
You will get a shock if you inspect the mess of RTF stuff W4W will put into
the clipboard if you copy just a few characters (the app below allows you to
inspect the clipboard), but you can get away with a lot less. The bare
minimum would be something like this (inserts an underlined 44444):
}
const
testtext: PChar = '{\rtf1\ansi\pard\plain 12{\ul 44444}}';
{
The correct balance of opening and closing braces is extremely important, one
mismatch and the target app will not be able to interpret the text
correctly. If you want to control the font used for the pasted text you need
to add a fonttable (the default font is Tms Rmn, not the active font in the
target app!). See example app below, testtext2. If you want more info, the
full RTF specs can be found on www.microsoft.com, a subset is also described
in the Windows help compiler docs (hcw.hlp, comes with Delphi).
}
unit Clipfmt1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
MemFormats: TMemo;
label1: TLabel;
BtnShowFormats: TButton;
BtnGetRTF: TButton;
BtnSetRTF: TButton;
MemExample: TMemo;
procedure FormCreate(Sender: TObject);
procedure BtnShowFormatsClick(Sender: TObject);
procedure BtnGetRTFClick(Sender: TObject);
procedure BtnSetRTFClick(Sender: TObject);
private
public
CF_RTF: Word;
end;
var
Form1: TForm1;
implementation
uses Clipbrd;
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
// register clipboard format rtf
CF_RTF := RegisterClipboardFormat('Rich Text Format');
if CF_RTF = 0 then
begin
ShowMessage('Unable to register the Rich Text clipboard format!');
Application.Terminate;
end;
BtnShowFormats.Click;
end;
// show clipboard formats
procedure TForm1.BtnShowFormatsClick(Sender: TObject);
var
buf: array [0..60] of Char;
n: Integer;
fmt: Word;
Name: string[30];
begin
MemFormats.Clear;
for n := 0 to Clipboard.FormatCount - 1 do
begin
fmt := Clipboard.Formats[n];
if GetClipboardFormatName(fmt, buf, Pred(SizeOf(buf))) <> 0 then
MemFormats.Lines.Add(StrPas(buf))
else
begin
case fmt of
1: Name := 'CF_TEXT';
2: Name := 'CF_BITMAP';
3: Name := 'CF_METAFILEPICT';
4: Name := 'CF_SYLK';
5: Name := 'CF_DIF';
6: Name := 'CF_TIFF';
7: Name := 'CF_OEMTEXT';
8: Name := 'CF_DIB';
9: Name := 'CF_PALETTE';
10: Name := 'CF_PENDATA';
11: Name := 'CF_RIFF';
12: Name := 'CF_WAVE';
13: Name := 'CF_UNICODETEXT';
14: Name := 'CF_ENHMETAFILE';
15: Name := 'CF_HDROP (Win 95)';
16: Name := 'CF_LOCALE (Win 95)';
17: Name := 'CF_MAX (Win 95)';
$0080: Name := 'CF_OWNERDISPLAY';
$0081: Name := 'CF_DSPTEXT';
$0082: Name := 'CF_DSPBITMAP';
$0083: Name := 'CF_DSPMETAFILEPICT';
$008E: Name := 'CF_DSPENHMETAFILE';
$0200..$02FF: Name := 'private format';
$0300..$03FF: Name := 'GDI object';
else
Name := 'unknown format';
end;
MemFormats.Lines.Add(Name);
end;
end;
end;
// get rtf code from clipboard
procedure TForm1.BtnGetRTFClick(Sender: TObject);
var
MemHandle: THandle;
begin
with Clipboard do
begin
Open;
try
if HasFormat(CF_RTF) then
begin
MemHandle := GetAsHandle(CF_RTF);
MemExample.SetTextBuf(GlobalLock(MemHandle));
GlobalUnlock(MemHandle);
end
else
MessageDlg('The clipboard contains no RTF text!',
mtError, [mbOK], 0);
finally
Close;
end;
end;
end;
// set rtf code to the clipboard
procedure TForm1.BtnSetRTFClick(Sender: TObject);
const
testtext: PChar = '{\rtf1\ansi\pard\plain 12{\ul 44444}}';
testtext2: PChar = '{\rtf1\ansi' +
'\deff4\deflang1033{\fonttbl{\f4\froman\fcharset0\fprq2 Times New Roman;}}' +
'\pard\plain 12{\ul 44444}}';
flap: Boolean = False;
var
MemHandle: THandle;
rtfstring: PChar;
begin
with Clipboard do
begin
if flap then
rtfstring := testtext2
else
rtfstring := testtext;
flap := not flap;
MemHandle := GlobalAlloc(GHND or GMEM_SHARE, StrLen(rtfstring) + 1);
if MemHandle <> 0 then
begin
StrCopy(GlobalLock(MemHandle), rtfstring);
GlobalUnlock(MemHandle);
Open;
try
AsText := '1244444';
SetAsHandle(CF_RTF, MemHandle);
finally
Close;
end;
end
else
MessageDlg('Global Alloc failed!',
mtError, [mbOK], 0);
end;
end;
end.
Взято с сайта
Как копировать векторное изображение?
Как копировать векторное изображение?
procedureTForm1.Button1Click(Sender: TObject);
var
mf: TMetaFile;
mfc: TMetaFileCanvas;
i: integer;
ClipBrdFormat: word;
data: cardinal;
palette: hPalette;
p: array [0..90] of TPoint;
begin
mf := TMetaFile.Create;
mf.Width := 100;
mf.Height := 100;
mfc := TMetafileCanvas.Create(mf, 0);
with mfc do
begin
Pen.Color := clBlack;
FrameRect(ClipRect);
MoveTo(0, 50);
LineTo(100, 50);
LineTo(95, 48);
MoveTo(100, 50);
LineTo(95, 52);
MoveTo(50, 100);
LineTo(50, 0);
LineTo(48, 5);
MoveTo(50, 0);
LineTo(52, 5);
Brush.Style := bsClear;
Font.name := 'arial';
Font.Size := 6;
TextOut(55, 0, 'Y');
TextOut(95, 38, 'X');
Pen.Color := clRed;
for i := low(p) to high(p) do
p[i] := Point(i, round(50 - 30 * sin((i - 50) / 5)));
Polyline(p);
end;
mfc.Free;
mf.SaveToClipboardFormat(ClipBrdFormat, data, palette);
OpenClipboard(Application.Handle);
EmptyClipboard;
SetClipboardData(ClipBrdFormat, data);
CloseClipboard;
mf.Inch := 200;
Form1.Canvas.Draw(0, 0, mf);
mf.Free;
end;
Взято с
Как корректно прервать выполнение SQL-запроса?
Как корректно прервать выполнение SQL-запроса?
Дает ли Delphi возможность корректно прервать выполнение SQL-запроса к серверу Oracle с помощью BDE? Например, чтобы при использовании с SQL Plus после отправки SQL-запроса на выполнение на экране появлялось окно с кнопкой Cancel, которое давало бы возможность в любой момент прервать выполнение этого запроса?
Насколько мне известно, для этой цели лучше всего использовать функции Oracle Call Interface (низкоуровневый API Oracle). В комплекте поставки Oracle есть соответствующие примеры для C, и переписать их на Pascal несложно.
Некоторые драйверы SQL Link позволяют прекратить выполнение запроса, если время его выполнения превышает заранее заданное значение (параметр MAX QUERY TIME соответствующего драйвера). Однако драйвер ORACLE, к сожалению, в их число не входит.
Взято из
Как локализовать (русифицировать) ресурсы какого-либо пакета (runtime package)?
Как локализовать (русифицировать) ресурсы какого-либо пакета (runtime package)?
1) Вынимаете pесуpсы из этого модуля.
2) Пеpеводите их на дpугой язык. (напpимеp pусский)
3) Создаете в Delphi свой пpоект Dll-ки (с именем того модуля, из котоpого вы
вынули pесуpсы, напpимеp vcl30), в котоpый включаете _пеpеведенные_
pесуpсы:
{$R vcl30rus.res}
4) Собиpаете все это.
5) Пеpеименовываете полученную vcl30.Dll в vcl30.rus и кидаете ее в System.
Если вы хотите, пpиложение "говоpило" по pусски только тогда, когда в
pегиональных установках стоит Russia - то тогда это все.
Если же вы хотите, чтобы ваше пpиложение _всегда_ поднимало pусские pесуpсы,
то необходимо сделать следующее добавление в Registry:
HKEY_CURRENT_USER\SOFTWARE\Borland\Delphi\Locales
"X:\MyProject\MyApp.exe" = "rus"
Тепеpь, когда ваше пpиложение будет поднимать pakages, то всегда будут бpаться
pусские pесуpсы. Дpугие пpиложения, напpимеp Delphi - это не затpонет.
Таким обpазом можно заменять даже DFM-ки из пpоекта.
Более подpобно об этом - см Help - Index - Localizing...
Alexander Simonenko .alex@protec.kiev.ua.(2:463/249)
Как менять шрифт в RichEdit горячими клавишами?
Как менять шрифт в RichEdit горячими клавишами?
Следующий пример показывает, как можно изменять шрифт в компоненте TRichEdit при помощи следующих комбинаций клавиш:
Ctrl + B - Включает и выключает жирность (Bold) шрифта
Ctrl + I - Включает и выключает (Italic) шрифта
Ctrl + S - Включает и выключает зачёркивание (Strikeout) шрифта
Ctrl + U - Включает и выключает подчёркивание (Underline) шрифта
Замечание: Так же можно устанавливать сразу несколько типов шрифта.
Пример:
const
KEY_CTRL_B = 02;
KEY_CTRL_I = 9;
KEY_CTRL_S = 19;
KEY_CTRL_U = 21;
procedure TForm1.RichEdit1KeyPress(Sender: TObject; var Key: Char);
begin
case Ord(Key) of
KEY_CTRL_B: begin
Key := #0;
if fsBold in (Sender as TRichEdit).SelAttributes.Style then
(Sender as TRichEdit).SelAttributes.Style :=
(Sender as TRichEdit).SelAttributes.Style - [fsBold] else
(Sender as TRichEdit).SelAttributes.Style :=
(Sender as TRichEdit).SelAttributes.Style + [fsBold];
end;
KEY_CTRL_I: begin
Key := #0;
if fsItalic in
(Sender as TRichEdit).SelAttributes.Style then
(Sender as TRichEdit).SelAttributes.Style :=
(Sender as TRichEdit).SelAttributes.Style - [fsItalic]
else
(Sender as TRichEdit).SelAttributes.Style :=
(Sender as TRichEdit).SelAttributes.Style + [fsItalic];
end;
KEY_CTRL_S: begin
Key := #0;
if fsStrikeout in
(Sender as TRichEdit).SelAttributes.Style then
(Sender as TRichEdit).SelAttributes.Style :=
(Sender as TRichEdit).SelAttributes.Style - [fsStrikeout]
else
(Sender as TRichEdit).SelAttributes.Style :=
(Sender as TRichEdit).SelAttributes.Style + [fsStrikeout];
end;
KEY_CTRL_U: begin
Key := #0;
if fsUnderline in
(Sender as TRichEdit).SelAttributes.Style then
(Sender as TRichEdit).SelAttributes.Style :=
(Sender as TRichEdit).SelAttributes.Style - [fsUnderline]
else
(Sender as TRichEdit).SelAttributes.Style :=
(Sender as TRichEdit).SelAttributes.Style + [fsUnderline];
end;
end;
end;
Взято с Исходников.ru
Как мне избавиться от выскакивающего окна CPU при ошибках?
Как мне избавиться от выскакивающего окна CPU при ошибках?
HKEY_CURRENT_USER\Software\Borland\Delphi\4.0\Debugging
ViewCPUOnException=0
Взято с сайта
Как мне отправить на принтер чистый поток данных?
Как мне отправить на принтер чистый поток данных?
Под Win16 Вы можете использовать функцию SpoolFile, или
Passthrough escape, если принтер поддерживает последнее.
Под Win32 Вы можете использовать WritePrinter.
'иже пример открытия принтера и записи чистого потока данных в принтер.
Учтите, что Вы должны передать корректное имя принтера, такое, как "HP LaserJet
5MP",
чтобы функция сработала успешно.
Конечно, Вы можете включать в поток данных любые необходимые управляющие коды,
которые могут потребоваться.
uses WinSpool;
procedure WriteRawStringToPrinter(PrinterName:String; S:String);
var
Handle: THandle;
N: DWORD;
DocInfo1: TDocInfo1;
begin
if not OpenPrinter(PChar(PrinterName), Handle, nil) then
begin
ShowMessage('error ' + IntToStr(GetLastError));
Exit;
end;
with DocInfo1 do begin
pDocName := PChar('test doc');
pOutputFile := nil;
pDataType := 'RAW';
end;
StartDocPrinter(Handle, 1, @DocInfo1);
StartPagePrinter(Handle);
WritePrinter(Handle, PChar(S), Length(S), N);
EndPagePrinter(Handle);
EndDocPrinter(Handle);
ClosePrinter(Handle);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
WriteRawStringToPrinter('HP', 'Test This');
end;
(Borland FAQ N714, переведен Акжаном Абдулиным)
Взято с сайта
Как мне узнать о воздействии мыши на иконку, находящуюся на Tray?
Как мне узнать о воздействии мыши на иконку, находящуюся на Tray?
При добавлении иконки на Tray вы указывали окно - обработчик сообщения и сообщение (CallbackMessage). Теперь окно, указанное вами будет при любых событиях мыши, происходящих над иконкой получать сообщение, указанное при добавлении иконки. При этом параметры lParam и wParam будут задействованы следующим образом:
(UINT)wParam - содержит ID иконки, над которой произошло
событие
(UINT)lParam - содержит стандартное событие мыши, такое
как WM_MOUSEMOVE или WM_LBUTTONDOWN.
При этом, информация о клавишах смены регистра, так же как и местоположения события, передаваемые при стандартных " настоящих" сообщениях мыши, теряются. Hо положение курсора можно узнать функцией GetCursorPos(), а состояние клавиш смены регистра - функцией GetKeyState(), описанных в winuser.h.
Взято из FAQ:
Как можно гарантированно очистить экран в консольном приложении?
Как можно гарантированно очистить экран в консольном приложении?
Автор: Олег Кулабухов
Нужно просто использовать GetConsoleScreenBufferInfo() для ввода нескольких пустых строк.
programProject1;
{$APPTYPE CONSOLE}
uses
Windows;
{$R *.RES}
var
sbi: TConsoleScreenBufferInfo;
i: integer;
begin
Writeln('A Console Applicaiton');
Writeln('Press Enter To Clear The Screen');
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),
sbi);
Readln;
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),
sbi);
for i := 0 to sbi.dwSize.y do
writeln;
Writeln('Press Enter To End');
Readln;
end.
Взято с
Как можно из своей программы закрыть чужую?
Как можно из своей программы закрыть чужую?
PostThreadMessage(AnotherProg_MainThreadID,WM_CLOSE,0,0);
PostMessage(AnotherProg_MainWindow,WM_CLOSE,0,0);
Автор ответа: Fantasist
Взято с Vingrad.ru
Автор ответа: LENIN INC
Взято с Vingrad.ru
Как можно определить Handle окна,над которым находится мышка?
Как можно определить Handle окна,над которым находится мышка?
WindowFromPoint
ChildWindowFromPoint
Автор ответа: rhf
Взято с Vingrad.ru
Как можно открыть отчёт (в режиме Print Preview а также print direct) в MS Access ?
Как можно открыть отчёт (в режиме Print Preview а также print direct) в MS Access ?
var
Access: Variant;
begin
// Открываем Access
try
Access := GetActiveOleObject('Access.Application');
except
Access := CreateOleObject('Access.Application');
end;
Access.Visible := True;
// Открываем базу данных
// Второй параметр указывает - будет ли база открыта в Exclusive режиме
Access.OpenCurrentDatabase('C:\My Documents\Books.mdb', True);
// открываем отч?т
{Значение второго пораметра может быть одним из следующих
acViewDesign, acViewNormal, or acViewPreview. acViewNormal,
которые устанавливаются по умолчанию, для печати отч?та.
Если Вы не используете библиотеку типов, то можете определить
эти значения следующими:
const
acViewNormal = $00000000;
acViewDesign = $00000001;
acViewPreview = $00000002;
Третий параметр - это имя очереди для текущей базы данных.
Четв?ртый параметр - это строка для SQL-евского WHERE -
то есть строка SQL, минус WHERE.}
Access.DoCmd.OpenReport('Titles by Author', acViewPreview, EmptyParam,
EmptyParam);
< ... >
// Закрываем базу данных
Access.CloseCurrentDatabase;
// Закрываем Access
{const
acQuitPrompt = $00000000;
acQuitSaveAll = $00000001;
acQuitSaveNone = $00000002;}
Access.Quit(acQuitSaveAll);
end;
Как можно отменить реакию ComboBox на F4?
procedure TForm1.ComboBox1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if key=vk_F4 then key:=0;
end;
Автор ответа: Vit
Взято с Vingrad.ru
Как можно перекодировать сообщение (содержание) из Win в КОИ8-Р для отправки по EMail?
Как можно перекодировать сообщение (содержание) из Win в КОИ8-Р для отправки по EMail?
const
Koi: Array[0..66] of Char = ("T", "Ё", "ё", "А", "Б", "В", "Г", "Д", "Е", "Ж",
"З", "И", "Й", "К", "Л", "М", "Н", "О", "П", "Р",
"С", "Т", "У", "Ф", "Х", "Ц", "Ч", "Ш", "Щ", "Ъ",
"Ы", "Ь", "Э", "Ю", "Я", "а", "б", "в", "г", "д",
"е", "ж", "з", "и", "й", "к", "л", "м", "н", "о",
"п", "р", "с", "т", "у", "ф", "х", "ц", "ч", "ш",
"щ", "ъ", "ы", "ь", "э", "ю", "я");
Win: Array[0..66] of Char = ("ё", "Ё", "T", "ю", "а", "б", "ц", "д", "е", "ф",
"г", "х", "и", "й", "к", "л", "м", "н", "о", "п",
"я", "р", "с", "т", "у", "ж", "в", "ь", "ы", "з",
"ш", "э", "щ", "ч", "ъ", "Ю", "А", "Б", "Ц", "Д",
"Е", "Ф", "Г", "Х", "И", "Й", "К", "Л", "М", "Н",
"О", "П", "Я", "Р", "С", "Т", "У", "Ж", "В", "Ь",
"Ы", "З", "Ш", "Э", "Щ", "Ч", "Ъ");
function WinToKoi(Str: String): String;
var
i, j, Index: Integer;
begin
Result := ""
for i := 1 to Length(Str) do
begin
Index := -1;
for j := Low(Win) to High(Win) do
if Win[j] = Str[i] then
begin
Index := j;
Break;
end;
if Index = -1 then Result := Result + Str[i]
else Result := Result + Koi[Index];
end;
end;
function KoiToWin(Str: String): String;
var
i, j, Index: Integer;
begin
Result := ""
for i := 1 to Length(Str) do
begin
Index := -1;
for j := Low(Win) to High(Win) do
if Koi[j] = Str[i] then
begin
Index := j;
Break;
end;
if Index = -1 then Result := Result + Str[i]
else Result := Result + Win[Index];
end;
end;
procedure SendFileOnSMTP(Host: String;
Port: Integer;
Subject,
FromAddress, ToAddress,
Body,
FileName: String);
var
NMSMTP: TNMSMTP;
begin
if DelSpace(ToAddress) = "" then Exit;
if ToAddress[1] = "" then Exit;
if (DelSpace(FileName) <> "") and not FileExists(FileName) then
raise Exception.Create("SendFileOnSMTP: file not exist: " + FileName);
NMSMTP := TNMSMTP.Create(nil);
try
NMSMTP.Host := Host;
NMSMTP.Port := Port;
NMSMTP.Charset := "koi8-r"
NMSMTP.PostMessage.FromAddress := FromAddress;
NMSMTP.PostMessage.ToAddress.Text := ToAddress;
NMSMTP.PostMessage.Attachments.Text := FileName;
NMSMTP.PostMessage.Subject := Subject;
NMSMTP.PostMessage.Date := DateTimeToStr(Now);
NMSMTP.UserID := "netmaster"
NMSMTP.PostMessage.Body.Text := WinToKoi(Body);
NMSMTP.FinalHeader.Clear;
NMSMTP.TimeOut := 5000;
NMSMTP.Connect;
NMSMTP.SendMail;
NMSMTP.Disconnect;
finally
NMSMTP.Free;
end;
end;
Взято с сайта
Как можно получить звук с микрофона?
Как можно получить звук с микрофона?
unit receiver;
interface
uses mmsystem, classes;
const
samp_per_sec = 44100;
samp_cnt = samp_per_sec div 5;
buf_len = samp_cnt * 2;
type
PSample16M = ^TSample16M;
TSample16M = SmallInt;
PArrayOfSample = ^TArrayOfSample;
TArrayOfSample = array[1..samp_cnt] of TSample16M;
TReceiver = class
private
hwi: Integer;
fmt: tWAVEFORMATEX;
whdr1: WAVEHDR;
buf1: TArrayOfSample;
whdr2: WAVEHDR;
buf2: TArrayOfSample;
FStoped: Boolean;
FOnChange: TNotifyEvent;
procedure SetStoped(const Value: Boolean);
public
Peak: Integer;
Buffer: PArrayOfSample;
destructor Destroy; override;
procedure Start;
procedure Stop;
property Stoped: Boolean read FStoped write SetStoped;
property OnChange: TNotifyEvent read FOnChange write FOnChange;
end;
var rec: TReceiver;
implementation
procedure waveInProc(const hwi, uMsg, dwInstance: Integer; var hdr: WAVEHDR; const dwP2: Integer); stdcall;
const divs = samp_cnt div 100;
var
i, p: Integer;
buf: PArrayOfSample;
begin
if rec.Stoped then Exit;
case uMsg of
WIM_OPEN: begin end;
WIM_DATA: begin
rec.Buffer := PArrayOfSample(hdr.lpData);
buf := PArrayOfSample(hdr.lpData);
p := 0;
for i := 0 to samp_cnt div divs do p := p + Abs(buf[i * divs]);
rec.Peak := p div (samp_cnt div divs);
if Assigned(rec.FOnChange) then rec.FOnChange(rec);
waveInUnprepareHeader(hwi, @hdr, SizeOf(WAVEHDR));
waveInPrepareHeader(hwi, @hdr, SizeOf(WAVEHDR));
waveInAddBuffer(hwi, @hdr, SizeOf(WAVEHDR));
end;
WIM_CLOSE: begin end;
end;
end;
{ TReceiver }
destructor TReceiver.Destroy;
begin
Stoped := True;
inherited;
end;
procedure TReceiver.SetStoped(const Value: Boolean);
begin
FStoped := Value;
if Value then
begin
waveInStop(hwi);
waveInUnprepareHeader(hwi, @whdr1, SizeOf(WAVEHDR));
waveInUnprepareHeader(hwi, @whdr2, SizeOf(WAVEHDR));
waveInReset(hwi);
waveInClose(hwi);
end
else
begin
with fmt do
begin
wFormatTag := WAVE_FORMAT_PCM;
nChannels := 1;
nSamplesPerSec := samp_per_sec;
nBlockAlign := 2;
nAvgBytesPerSec := nSamplesPerSec * nBlockAlign;
wBitsPerSample := 16;
cbSize := 0;
end;
waveInOpen(@hwi, WAVE_MAPPER, @fmt, Cardinal(@waveInProc), hInstance, CALLBACK_FUNCTION);
with whdr1 do
begin
lpData := @buf1;
dwBufferLength := buf_len;
dwBytesRecorded := 0;
dwUser := 0;
dwFlags := 0;
dwLoops := 0;
lpNext := nil;
reserved := 0;
end;
waveInPrepareHeader(hwi, @whdr1, SizeOf(WAVEHDR));
waveInAddBuffer(hwi, @whdr1, SizeOf(WAVEHDR));
with whdr2 do
begin
lpData := @buf2;
dwBufferLength := buf_len;
dwBytesRecorded := 0;
dwUser := 0;
dwFlags := 0;
dwLoops := 0;
lpNext := nil;
reserved := 0;
end;
waveInPrepareHeader(hwi, @whdr2, SizeOf(WAVEHDR));
waveInAddBuffer(hwi, @whdr2, SizeOf(WAVEHDR));
waveInStart(hwi);
end;
end;
procedure TReceiver.Start;
begin
Stoped := False;
end;
procedure TReceiver.Stop;
begin
Stoped := True;
end;
initialization
rec := TReceiver.Create;
finalization
rec.Free;
end.
вот. отображать уровень можно через поле Peak при событии OnChange, там же (в этом событии) можно работать с полем Buffer в котором как раз содержется записанный сигнал.
Вся работа осуществляется через глобальную переменную rec . Возможно это не лучшая реализация с точки зрения ООП, но работает Запись происходит с глубиной 16 бит и частотой 44100 в режиме моно. После небольшой переделки все это может работать с любыми частотами и каналами и глубинами.
Автор cully
Взято с Vingrad.ru