Delphi - база знаний

         

Как послать сообщение?


Как послать сообщение?






  You need 3 TEdits, 1 TMemo und 1 TClientSocket. 
  Set the  TClientsocket's Port to 80 and the Host to wwp.mirabilis.com. 


var 
  Form1: TForm1; 
  csend: string; 

implementation 

{$R *.dfm} 



procedure TForm1.Button1Click(Sender: TObject); 
begin 
  cSend := 'POST http://wwp.icq.com/scripts/WWPMsg.dll HTTP/2.0' + chr(13) + chr(10); 
  cSend := cSend + 'Referer: http://wwp.mirabilis.com' + chr(13) + chr(10); 
  cSend := cSend + 'User-Agent: Mozilla/4.06 (Win95; I)' + chr(13) + chr(10); 
  cSend := cSend + 'Connection: Keep-Alive' + chr(13) + chr(10); 
  cSend := cSend + 'Host: wwp.mirabilis.com:80' + chr(13) + chr(10); 
  cSend := cSend + 'Content-type: application/x-www-form-urlencoded' + chr(13) + chr(10); 
  cSend := cSend + 'Content-length:8000' + chr(13) + chr(10); 
  cSend := cSend + 'Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*' + 
    chr(13) + chr(10) + chr(13) + chr(10); 
  cSend := cSend + 'from=' + edit1.Text + ' &fromemail=' + edit2.Text + 
    ' &fromicq:110206786' + ' &body=' + memo1.Text + ' &to=' + edit3.Text + '&Send='; 
  clientsocket1.Active := True; 
end; 

procedure TForm1.ClientSocket1Connect(Sender: TObject; 
  Socket: TCustomWinSocket); 
begin 
  clientsocket1.Socket.SendText(csend); 
  clientsocket1.Active := False; 
end; 

Взято с сайта



Как послать сообщение всем окнам Windows?


Как послать сообщение всем окнам Windows?




Var
FM_FINDPHOTO:Integer;
// Для использовать hwnd_Broadcast нужно сперва
// зарегистрировать уникальное сообщение
Initialization
FM_FindPhoto:=RegisterWindowMessage('MyMessageToAll');
// Чтобы поймать это сообщение в другом приложении
//(приемнике) нужно перекрыть DefaultHandler
procedure TForm1.DefaultHandler(var Message);
begin
 with TMessage(Message) do
 begin
   if Msg = Fm_FindPhoto then MyHandler(WPARAM,LPARAM)  else
   Inherited DefaultHandler(Message);
 end;

end;

// А тепрь можно
SendMessage(HWND_BROADCAST,FM_FINDPHOTO,0,0);

Кстати, для посылки сообщения дочерним контролам некоего контрола можно использовать метод Broadcast.

АвторAndrey Burov
(2:463/238.19)

Автор:

StayAtHome

Взято из





Как повернуть Bitmap на любой угол


Как повернуть Bitmap на любой угол



ConstPixelMax = 32768;
Type
  pPixelArray  =  ^TPixelArray;
  TPixelArray  =  Array[0..PixelMax-1] Of TRGBTriple;

Procedure RotateBitmap_ads(
  SourceBitmap   : TBitmap;
  out DestBitmap : TBitmap;
  Center         : TPoint;
  Angle          : Double);
Var
  cosRadians          : Double;
  inX                 : Integer;
  inXOriginal         : Integer;
  inXPrime            : Integer;
  inXPrimeRotated     : Integer;
  inY                 : Integer;
  inYOriginal         : Integer;
  inYPrime            : Integer;
  inYPrimeRotated     : Integer;
  OriginalRow         : pPixelArray;
  Radians             : Double;
  RotatedRow          : pPixelArray;
  sinRadians          : Double;
begin
  DestBitmap.Width    := SourceBitmap.Width;
  DestBitmap.Height   := SourceBitmap.Height;
  DestBitmap.PixelFormat := pf24bit;
  Radians             := -(Angle) * PI / 180;
  sinRadians          := Sin(Radians);
  cosRadians          := Cos(Radians);
  For inX             := DestBitmap.Height-1 Downto 0 Do
  Begin
    RotatedRow        := DestBitmap.Scanline[inX];
    inXPrime          := 2*(inX - Center.y) + 1;
    For inY           := DestBitmap.Width-1 Downto 0 Do
    Begin
      inYPrime        := 2*(inY - Center.x) + 1;
      inYPrimeRotated := Round(inYPrime * CosRadians - inXPrime * sinRadians);
      inXPrimeRotated := Round(inYPrime * sinRadians + inXPrime * cosRadians);
      inYOriginal     := (inYPrimeRotated - 1) Div 2 + Center.x;
      inXOriginal     := (inXPrimeRotated - 1) Div 2 + Center.y;
      If
        (inYOriginal  >= 0)                    And
        (inYOriginal  <= SourceBitmap.Width-1) And
        (inXOriginal  >= 0)                    And
        (inXOriginal  <= SourceBitmap.Height-1)
      Then
      Begin
        OriginalRow   := SourceBitmap.Scanline[inXOriginal];
        RotatedRow[inY]  := OriginalRow[inYOriginal]
      End
      Else
      Begin
        RotatedRow[inY].rgbtBlue  := 255;
        RotatedRow[inY].rgbtGreen := 0;
        RotatedRow[inY].rgbtRed   := 0
      End;
    End;
  End;
End;

{Usage:}
procedure TForm1.Button1Click(Sender: TObject);
Var
  Center : TPoint;
  Bitmap : TBitmap;
begin
  Bitmap := TBitmap.Create;
  Try
    Center.y := (Image.Height  div 2)+20;
    Center.x := (Image.Width div 2)+0;
    RotateBitmap_ads(
      Image.Picture.Bitmap,  
      Bitmap,  
      Center,  
      Angle);
    Angle := Angle + 15;
    Image2.Picture.Bitmap.Assign(Bitmap);
  Finally
    Bitmap.Free;
  End;
end;

Взято с Исходников.ru


procedure RotateBitmap(Bitmap: TBitmap; Angle: Double; BackColor: TColor);
type TRGB = record
       B, G, R: Byte;
     end;
     pRGB = ^TRGB;
     pByteArray = ^TByteArray;
     TByteArray = array[0..32767] of Byte;
     TRectList = array [1..4] of TPoint;

var x, y, W, H, v1, v2: Integer;
    Dest, Src: pRGB;
    VertArray: array of pByteArray;
    Bmp: TBitmap;

  procedure SinCos(AngleRad: Double; var ASin, ACos: Double);
  begin
    ASin := Sin(AngleRad);
    ACos := Cos(AngleRad);
  end;

  function RotateRect(const Rect: TRect; const Center: TPoint; Angle: Double): TRectList;
  var DX, DY: Integer;
      SinAng, CosAng: Double;
    function RotPoint(PX, PY: Integer): TPoint;
    begin
      DX := PX - Center.x;
      DY := PY - Center.y;
      Result.x := Center.x + Round(DX * CosAng - DY * SinAng);
      Result.y := Center.y + Round(DX * SinAng + DY * CosAng);
    end;
  begin
    SinCos(Angle * (Pi / 180), SinAng, CosAng);
    Result[1] := RotPoint(Rect.Left, Rect.Top);
    Result[2] := RotPoint(Rect.Right, Rect.Top);
    Result[3] := RotPoint(Rect.Right, Rect.Bottom);
    Result[4] := RotPoint(Rect.Left, Rect.Bottom);
  end;

  function Min(A, B: Integer): Integer;
  begin
    if A < B then Result := A
             else Result := B;
  end;

  function Max(A, B: Integer): Integer;
  begin
    if A > B then Result := A
             else Result := B;
  end;

  function GetRLLimit(const RL: TRectList): TRect;
  begin
    Result.Left := Min(Min(RL[1].x, RL[2].x), Min(RL[3].x, RL[4].x));
    Result.Top := Min(Min(RL[1].y, RL[2].y), Min(RL[3].y, RL[4].y));
    Result.Right := Max(Max(RL[1].x, RL[2].x), Max(RL[3].x, RL[4].x));
    Result.Bottom := Max(Max(RL[1].y, RL[2].y), Max(RL[3].y, RL[4].y));
  end;

  procedure Rotate;
  var x, y, xr, yr, yp: Integer;
      ACos, ASin: Double;
      Lim: TRect;
  begin
    W := Bmp.Width;
    H := Bmp.Height;
    SinCos(-Angle * Pi/180, ASin, ACos);
    Lim := GetRLLimit(RotateRect(Rect(0, 0, Bmp.Width, Bmp.Height), Point(0, 0), Angle));
    Bitmap.Width := Lim.Right - Lim.Left;
    Bitmap.Height := Lim.Bottom - Lim.Top;
    Bitmap.Canvas.Brush.Color := BackColor;
    Bitmap.Canvas.FillRect(Rect(0, 0, Bitmap.Width, Bitmap.Height));
    for y := 0 to Bitmap.Height - 1 do begin
      Dest := Bitmap.ScanLine[y];
      yp := y + Lim.Top;
      for x := 0 to Bitmap.Width - 1 do begin
        xr := Round(((x + Lim.Left) * ACos) - (yp * ASin));
        yr := Round(((x + Lim.Left) * ASin) + (yp * ACos));
        if (xr > -1) and (xr < W) and (yr > -1) and (yr < H) then begin
          Src := Bmp.ScanLine[yr];
          Inc(Src, xr);
          Dest^ := Src^;
        end;
        Inc(Dest);
      end;
    end;
  end;

begin
  Bitmap.PixelFormat := pf24Bit;
  Bmp := TBitmap.Create;
  try
    Bmp.Assign(Bitmap);
    W := Bitmap.Width - 1;
    H := Bitmap.Height - 1;
    if Frac(Angle) <> 0.0
      then Rotate
      else
    case Trunc(Angle) of
      -360, 0, 360, 720: Exit;
      90, 270: begin
        Bitmap.Width := H + 1;
        Bitmap.Height := W + 1;
        SetLength(VertArray, H + 1);
        v1 := 0;
        v2 := 0;
        if Angle = 90.0 then v1 := H
                        else v2 := W;
        for y := 0 to H do VertArray[y] := Bmp.ScanLine[Abs(v1 - y)];
        for x := 0 to W do begin
          Dest := Bitmap.ScanLine[x];
          for y := 0 to H do begin
            v1 := Abs(v2 - x)*3;
            with Dest^ do begin
              B := VertArray[y, v1];
              G := VertArray[y, v1+1];
              R := VertArray[y, v1+2];
            end;
            Inc(Dest);
          end;
        end
      end;
      180: begin
        for y := 0 to H do begin
          Dest := Bitmap.ScanLine[y];
          Src := Bmp.ScanLine[H - y];
          Inc(Src, W);
          for x := 0 to W do begin
            Dest^ := Src^;
            Dec(Src);
            Inc(Dest);
          end;
        end;
      end;
      else Rotate;
    end;
  finally
    Bmp.Free;
  end;
end;

// Использование
RotateBitmap(Image1.Picture.Bitmap, StrToInt(Edit1.Text), clWhite);

Взято из





Как повернуть элипс?


Как повернуть элипс?




procedureTForm1.EllipseAngle(ACanvas: TCanvas; XCenter, YCenter,
  XRadius, YRadius: Integer; Angle: Integer);
const
  Step = 49;
var
  RX, RY: Integer;
  i: Integer;
  Theta: Double;
  SAngle, CAngle: Double;
  RotAngle: Double;
  XC, YC: Integer;
  Kf: Double;
  X, Y: Double;
  XRot, YRot: Integer;
  Points: array[0..Step] of TPoint;
begin
  RotAngle := Angle * PI / 180;
  Kf := (360 * PI / 180) / Step;
  SAngle := Sin(RotAngle);
  CAngle := Cos(RotAngle);
  for i := 0 to Step do
  begin
    Theta := i * Kf;
    X := XCenter + XRadius * Cos(Theta);
    Y := YCenter + YRadius * Sin(Theta);
    XRot := Round(XCenter + (X - XCenter) * CAngle - (Y - YCenter) * SAngle);
    YRot := Round(YCenter + (X - XCenter) * SAngle + (Y - YCenter) * CAngle);
    Points[i] := Point(XRot, YRot);
  end;
  ACanvas.Polygon(Points);
end;


procedure RotatedEllipse(aCanvas: TCanvas; X1, Y1, X2, Y2: Integer);
var
  T, O: TXForm; {in unit Windows}
begin
  { ... }
  SetGraphicsMode(aCanvas.Handle, GM_Advanced);
  GetWorldTransform(aCanvas.Handle, O);
  {Angle in degree}
  T.eM11 := 1 * Cos(w / 360 * Pi * 2);
  T.eM22 := 1 * Cos(w / 360 * Pi * 2);
  T.eM12 := 1 * Sin(w / 360 * Pi * 2);
  T.eM21 := 1 * -Sin(w / 360 * Pi * 2);
  T.eDX := Round((X1 + X2) / 2);
  T.eDY := Round((Y1 + Y2) / 2);
  ModifyWorldTransform(aCanvas.Handle, T, MWT_LEFTMULTIPLY);
  Canvas.Ellipse(X1, Y1, X2, Y2);
  SetWorldTransform(TheDraw.Handle, O);
end;

Взято с

Delphi Knowledge Base






Как пpинимать яpлыки пpи пеpетягивании их на контpол


Как пpинимать яpлыки пpи пеpетягивании их на контpол




Автор: Nomadic



TForm1= class(TForm)
  ...
  private
    { Private declarations }
    procedure WMDropFiles(var M: TWMDropFiles); message WM_DROPFILES;
  ...
end;

var
  Form1: TForm1;

implementation

uses
  StrUtils, ShellAPI, ComObj, ShlObj, ActiveX;

procedure TForm1.FormCreate(Sender: TObject);
begin
  ...
  DragAcceptFiles(Handle, True);
  ...
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  ...
  DragAcceptFiles(Handle, False);
  ...
end;

procedure TForm1.WMDropFiles(var M: TWMDropFiles);
var
  hDrop: Cardinal;
  n: Integer;
  s: string;
begin
  hDrop := M.Drop;
  n := DragQueryFile(hDrop, 0, nil, 0);
  SetLength(s, n);
  DragQueryFile(hDrop, 0, PChar(s), n + 1);
  DragFinish(hDrop);
  M.Result := 0;
  FileOpen(s);
end;

procedure TForm1.FileOpen(FileName: string);
begin
  if CompareText(ExtractFileExt(FileName), '.lnk') = 0 then
    FileName := ResolveShortcut(Application.Handle, FileName);
  DocName := ExtractFileName(FileName);
  Caption := Application.Title + ' - ' + DocName;
  ...
end;

function ResolveShortcut(Wnd: HWND; ShortcutPath: string): string;
var
  obj: IUnknown;
  isl: IShellLink;
  ipf: IPersistFile;
  pfd: TWin32FindDataA;
begin
  Result := '';
  obj := CreateComObject(CLSID_ShellLink);
  isl := obj as IShellLink;
  ipf := obj as IPersistFile;
  ipf.Load(PWChar(WideString(ShortcutPath)), STGM_READ);
  with isl do
  begin
    Resolve(Wnd, SLR_ANY_MATCH);
    SetLength(Result, MAX_PATH);
    GetPath(PChar(Result), Length(Result), pfd, SLGP_UNCPRIORITY);
    Result := PChar(Result);
  end;
end;


Взято с





Как правильно печатать любую информацию


Как правильно печатать любую информацию (растровые и векторные изображения), а также как сделать режим предварительного просмотра?



Маленькое пpедисловие.


Т.к. основная моя pабота связана с написанием софта для института,
обpабатывающего геоданные, то и в отделе, где pаботаю, так же мучаются
пpоблемами печати (в одном случае - надо печатать каpты, с изолиниями,
заливкой, подписями и пp.; в дpугом случае - свои таблицы и сложные отpисовки
по внешнему виду).
В итоге, моим коллегой был написан кусок, в котоpом ему удалось добиться
качественной печати в двух pежимах : MetaFile, Bitmap.
Работа с MetaFile у нас сложилась уже истоpически - достаточно удобно

описать ф-цию, котоpая что-то отpисовыват (хоть на экpане, хоть где), котоpая
пpинимает TCanvas, и подсовывать ей то канвас дисплея, то канвас метафайла, а
потом этот Metafile выбpасывать на печать.
Достаточно pешить лишь пpоблемы масштабиpования, после чего - впеpед.

Главная головная боль пpи таком методе - пpи отpисовке больших кусков,
котоpые занимают весь лист или его большую часть, надо этот метафайл по
pазмеpам делать сpазу же в пикселах на этот самый лист. Тогда пpи изменении

pазмеpов (пpосмотp пеpед печатью) - искажения пpи уменьшении не кpитичны, а вот
пpи увеличении линии и шpифты не "поползут".

Итак :

Hабоp идей, котоpые были написаны (с) Андpеем Аpистовым, пpогpаммистом
отдела матобеспечения СибHИИHП, г. Тюмень. Моего здесь только - пpиделывание
свеpху надстpоек для личного использования.

Вся pабота сводится к следующим шагам :

1. Получить необходимые коэф-ты.
2. Постpоить метафайл или bmp для последующего вывода на печать.

3. Hапечатать.

Hиже пpиведенный кусок (пpошу меня не пинать, но писал я и писал для
достаточно кpивой pеализации с пеpедачей паpаметpов чеpез глобальные
пеpеменные) я использую для того, чтобы получить коэф-ты пеpесчета.

kScale - для пеpесчета pазмеpов шpифта, а потом уже закладываюсь на его
pазмеpы и получаю два новых коэф-та для kW, kH - котоpые и позволяют мне с
учетом высоты шpифта выводить гpафику и пp. У меня пpи pаботе kW <> kH, что
пpиходится учитывать.

Решили пункт 1.

procedure SetKoeffMeta; // установить коэф-ты
var
  PrevMetafile : TMetafile;
  MetaCanvas : TMetafileCanvas;
begin
  PrevMetafile  :=  nil;
  MetaCanvas    :=  nil;
  try
    PrevMetaFile  :=  TMetaFile.Create;
    try
      MetaCanvas  :=  TMetafileCanvas.Create( PrevMetafile, 0 );
      kScale := GetDeviceCaps( Printer.Handle, LOGPIXELSX ) /
Screen.PixelsPerInch;
      MetaCanvas.Font.Assign( oGrid.Font);
      MetaCanvas.Font.Size := Round( oGrid.Font.Size * kScale );

      kW := MetaCanvas.TextWidth('W') /  oGrid.Canvas.TextWidth('W');
      kH := MetaCanvas.TextHeight('W') / oGrid.Canvas.TextHeight('W');
    finally
      MetaCanvas.Free;
    end;
  finally
    PrevMetafile.Free;
  end;
end;

Решаем 2.

...
var
  PrevMetafile : TMetafile;
  MetaCanvas : TMetafileCanvas;
begin
  PrevMetafile  :=  nil;
  MetaCanvas    :=  nil;

  try
    PrevMetaFile  :=  TMetaFile.Create;

    PrevMetafile.Width  :=  oWidth;

    PrevMetafile.Height :=  oHeight;

    try
      MetaCanvas  :=  TMetafileCanvas.Create( PrevMetafile, 0 );

      // здесь должен быть ваш код - с учетом масштабиpования.
      // я эту вещь вынес в ассигнуемую пpоцедуpу, и данный блок
      // вызываю лишь для отpисовки целой стpаницы.

      см. PS1.

    finally
      MetaCanvas.Free;
    end;
...

PS1. Код, котоpый используется для отpисовки. oCanvas - TCanvas метафайла.

...
var
  iHPage : integer; // высота страницы

begin
  with oCanvas do begin

    iHPage := 3000;

   // залили область метайфайла белым - для дальнейшей pаботы
    Pen.Color   := clBlack;
    Brush.Color := clWhite;
    FillRect( Rect( 0, 0, 2000, iHPage ) );

   // установили шpифты - с учетом их дальнейшего масштабиpования
    oCanvas.Font.Assign( oGrid.Font);
    oCanvas.Font.Size := Round( oGrid.Font.Size * kScale );

...
    xEnd := xBegin;
    iH := round( RowHeights[ iRow ] * kH );
    for iCol := 0 to ColCount - 1 do begin

      x := xEnd;
      xEnd := x + round( ColWidths[ iCol ] * kW );
      Rectangle( x, yBegin, xEnd, yBegin + iH );
      r := Rect( x + 1, yBegin + 1, xEnd - 1, yBegin + iH - 1 );
      s := Cells[ iCol, iRow ];

      // выписали в полученный квадрат текст
      DrawText( oCanvas.Handle, PChar( s ), Length( s ), r, DT_WORDBREAK or
DT_CENTER );

Главное, что важно помнить на этом этапе - это не забывать, что все
выводимые объекты должны пользоваться описанными коэф-тами (как вы их получите

- это уже ваше дело). В данном случае - я pаботаю с пеpеделанным TStringGrid,
котоpый сделал для многостpаничной печати.

Последний пункт - надо сфоpмиpованный метафайл или bmp напечатать.

...
var
  Info: PBitmapInfo;
  InfoSize: Integer;
  Image: Pointer;
  ImageSize: DWORD;
  Bits: HBITMAP;
  DIBWidth, DIBHeight: Longint;
  PrintWidth, PrintHeight: Longint;
begin
...

  case ImageType of

    itMetafile: begin
      if Picture.Metafile<>nil then

        Printer.Canvas.StretchDraw( Rect(aLeft, aTop, aLeft+fWidth,
                 aTop+fHeight), Picture.Metafile);
    end;

    itBitmap: begin

      if Picture.Bitmap<>nil then begin
        with Printer, Canvas do begin
          Bits := Picture.Bitmap.Handle;
          GetDIBSizes(Bits, InfoSize, ImageSize);
          Info := AllocMem(InfoSize);
          try
            Image := AllocMem(ImageSize);
            try
              GetDIB(Bits, 0, Info^, Image^);

              with Info^.bmiHeader do begin
                DIBWidth := biWidth;
                DIBHeight := biHeight;
              end;
              PrintWidth := DIBWidth;
              PrintHeight := DIBHeight;
              StretchDIBits(Canvas.Handle, aLeft, aTop, PrintWidth,
                        PrintHeight, 0, 0, DIBWidth, DIBHeight, Image, Info^,
                        DIB_RGB_COLORS, SRCCOPY);
            finally
              FreeMem(Image, ImageSize);

            end;
          finally
            FreeMem(Info, InfoSize);
          end;
        end;
      end;
    end;
  end;


В чем заключается идея PreView ? Остается имея на pуках Metafila, Bmp -
отpисовать с пеpесчетом внешний вид изобpажения (надо высчитать левый веpхний
угол и pазмеpы "пpедваpительно пpосматpиваемого" изобpажения.
Для показа изобpажения достаточно использовать StretchDraw.

После того, как удалось вывести объекты на печать, пpоблему создания PreView

pешили как "домашнее задание".

Кстати, когда мы pаботаем с Bmp, то для пpосмотpа используем следующий хинт
- записываем битовый обpаз чеpез такую пpоцедуpу :

    w:=MulDiv(Bmp.Width,GetDeviceCaps(Printer.Handle,LOGPIXELSX),Screen.Pixels
              PerInch);
    h:=MulDiv(Bmp.Height,GetDeviceCaps(Printer.Handle,LOGPIXELSY),Screen.Pixel
              sPerInch);
    PrevBmp.Width:=w;
    PrevBmp.Height:=h;
    PrevBmp.Canvas.StretchDraw(Rect(0,0,w,h),Bmp);

    aPicture.Assign(PrevBmp);


Пpи этом масштабиpуется битовый обpаз с минимальными искажениями, а вот пpи
печати - пpиходится bmp печатать именно так, как описано выше.
Итог - наша bmp пpи печати чуть меньше, чем печатать ее чеpез WinWord, но
пpи этом - внешне - без каких-либо искажений и пp.

Imho, я для себя пpоблему печати pешил. Hа основе вышесказанного, сделал
PreView для myStringGrid, где вывожу сложные многостpочные заголовки и пp. на

несколько листов, осталось кое-что допилить, но с пpинтеpом у меня пpоблем не
будет уже точно :)

PS. Кстати, Андpей Аpистов на основе своей наpаботки сделал сложные
геокаpты, котоpые по качестве _не_хуже_, а может и лучше, чем выдает Surfer
(специалисты поймут). Hа ватмат.

PPS. Пpошу пpощения за возможные стилистические неточности - вpемя вышло,
охpана уже pугается. Hо код - выдpан из pаботающих исходников.

Боpисов Олег Hиколаевич (ZB)
panterra@sbtx.tmn.ru

(2:5077/5)

Взято с сайта



Как правильно работать с прозрачными окнами?


Как правильно работать с прозрачными окнами?




Как правильно работать с прозрачными окнами (стиль WS_EX_TRANSPARENT)?

Стиль окна-формы указывается в CreateParams. Только вот когда перемещаешь его, фон остается со старым куском экрана. Чтобы этого не происходило, то когда pисуешь своё окно, запоминай, что было под ним,а пpи пеpемещении восстанавливай.
HDC hDC = GetDC(GetDesktopWindow()) тебе поможет..
Andrei Bogomolov
http://cardy.hypermart.net
ICQ UIN:7329451
admin@cardy.hypermart.net
e-pager: 7329451@pager.mirabilis.com
(2:5013/11.3)

Автор:

StayAtHome

Взято из





Как предотвратить появление login dialog?


Как предотвратить появление login dialog?





To bypass the login dialog when connecting to a server database, use the property LoginPrompt.You will have to provide the username & password at runtime, but you also can set that up at design time in the object inspector, property Params.

This short source code shows how to do it:

Database1.LoginPrompt:= false;
with Database1.Params do
begin
  Clear;
  // the parameters SYSDBA & masterkey should be
  // retrieved somewhat different :-)
  Add('USER NAME=SYSDBA');
  Add('PASSWORD=masterkey');
end;
Database1.Connected := tr

Взято с

Delphi Knowledge Base




Как предотвратить утечки памяти при возникновении ошибок?


Как предотвратить утечки памяти при возникновении ошибок?



Используйте конструкцию

Try
  {здесь вы пишите код в котором может произойти ошибка}
Finally
  {здесь вы пишите код который выполнится в любом случае - хоть произойдёт ошибка, хоть нет}
End

Например, это часто применяется во избежание утечек при динамическом распределении памяти:

t:TStringList;
...
t:=TStringList.create; //распределили память под объект t
Try
  {здесь работаем с переменной t}
Finally
  t.free;//память выделенная под объект t всегда будет освобождена 
End

Автор Vit



Как представить число в другой системе счисления?


Как представить число в другой системе счисления?





function BaseConvert(NumIn: string; BaseIn: Byte; BaseOut: Byte): string; 
var 
  i: integer; 
  currentCharacter: char; 
  CharacterValue: Integer; 
  PlaceValue: Integer; 
  RunningTotal: Double; 
  Remainder: Double; 
  BaseOutDouble: Double; 
  NumInCaps: string; 
  s: string; 
begin 
  if (NumIn = '') or (BaseIn < 2) or (BaseIn > 36) or (BaseOut < 1) or (BaseOut > 36) then 
  begin 
    Result := 'Error'; 
    Exit; 
  end; 

  NumInCaps    := UpperCase(NumIn); 
  PlaceValue   := Length(NumInCaps); 
  RunningTotal := 0; 

  for i := 1 to Length(NumInCaps) do 
  begin 
    PlaceValue       := PlaceValue - 1; 
    CurrentCharacter := NumInCaps[i]; 
    CharacterValue   := 0; 
    if (Ord(CurrentCharacter) > 64) and (Ord(CurrentCharacter) < 91) then 
      CharacterValue := Ord(CurrentCharacter) - 55; 

    if CharacterValue = 0 then 
      if (Ord(CurrentCharacter) < 48) or (Ord(CurrentCharacter) > 57) then 
      begin 
        BaseConvert := 'Error'; 
        Exit; 
      end  
      else 
        CharacterValue := Ord(CurrentCharacter); 

    if (CharacterValue < 0) or (CharacterValue > BaseIn - 1) then 
    begin 
      BaseConvert := 'Error'; 
      Exit; 
    end; 
    RunningTotal := RunningTotal + CharacterValue * (Power(BaseIn, PlaceValue)); 
  end; 

  while RunningTotal > 0 do  
  begin 
    BaseOutDouble := BaseOut; 
    Remainder     := RunningTotal - (int(RunningTotal / BaseOutDouble) * BaseOutDouble); 
    RunningTotal  := (RunningTotal - Remainder) / BaseOut; 

    if Remainder >= 10 then 
      CurrentCharacter := Chr(Trunc(Remainder + 55)) 
    else 
    begin 
      s := IntToStr(trunc(remainder)); 
      CurrentCharacter := s[Length(s)]; 
    end; 
    Result := CurrentCharacter + Result; 
  end; 
end; 

// Example, Beispiel 

procedure TForm1.Button1Click(Sender: TObject); 
begin 
  BaseConvert('FFFF', 16, 10); 
  // returns, ergibt '65535'. 
end; 

Взято с сайта


Решение от Борланд:

The following function will convert a number from one base to
a number of another base:

procedure RadixStr(NumStr : pChar;
Radix : LongInt;
ResultStr : pChar;
NewRadix : LongInt;
var ErrorCode : LongInt);

The RadixStr() function takes a pointer to a null terminated string
containing a number of one base, and fills a buffer with a null
terminated string containing the number converted to another base.

Parameters:

NumStr: A pointer to a null terminated string containing the numeric
string to convert:

Radix: The base of the number contained in the NumStr parameter. The
base must be in the range of 2 to 36;

ResultStr : A pointer to a null terminated string buffer to place the
resulting numeric string. The buffer should be sufficiently large to
hold the resulting string.

NewRadix: The base to use in the conversion. The base must be in the
range of 2 to 36;

ErrorCode: Upon return, contains the return code 0 if successful, or
the character number of the offending character contained in the
buffer NumStr.

Examples of calling the RadixStr() function:

{Convert Hex to Decimal}
RadixStr('FF',
         16,
         lpBuffer,
         10,
         Code);

Should return the string '255' in lpbuffer^.

{Convert Decimal to Binary}
RadixStr('255',
         10,
         lpBuffer,
         2,
         Code);

Should return the string '11111111' in lpbuffer^.

{Convert Hex to Octal}
RadixStr('FF',
         16,
         lpBuffer,
         8,
         Code);

Should return the string '377' in lpbuffer^.

{Function code}

procedure RadixStr(NumStr : pChar;
                   Radix : LongInt;
                   ResultStr : pChar;
                   NewRadix : LongInt;
                   var ErrorCode : LongInt);
var
  RadixChar : array[0..35] of Char;
  v : LongInt;
  i : LongInt;
  p : LongInt;
  c : Integer;
begin
  if ((Abs(Radix) < 2) or
      (Abs(Radix) > 36)) then begin
    ErrorCode := p;
    Exit;
  end;
  StrLCopy(ResultStr, NumStr, StrLen(NumStr));
  for i := 0 to 35 do begin
    if i <= 9 then
      RadixChar[i] := Char(48 + (i))
    else
      RadixChar[i] := Char(64 + (i - 9))
  end;
  v := 0;
  for i := 0 to (StrLen(ResultStr) - 1) do begin
    ResultStr[i] := UpCase(ResultStr[i]);
    p := Pos(ResultStr[i], PChar(@RadixChar)) - 1;
    if ((p < 0) or
        (p >= Abs(Radix))) then begin
      ErrorCode := i;
      Exit;
    end;
    v := v * Abs(Radix) + p;
  end;
  if v = 0 then begin
    ResultStr := '0';
    ErrorCode := 0;
    exit;
  end else begin
    i:=0;
    repeat
      ResultStr[i] := RadixChar[v mod NewRadix];
      v := v div NewRadix;
      Inc(i)
    until v = 0;
    if Radix < 0 then begin
      ResultStr[i] := '-';
      ResultStr[i + 1] := #0
    end else
      ResultStr[i] := #0;
    p := StrLen(ResultStr);
    for i := 0 to ((p div 2) - 1) do begin
      ResultStr[i] := Char(Byte(ResultStr[i]) xor
                           Byte(ResultStr[(p - i) - 1]));
      ResultStr[(p - i) - 1] := Char(Byte(ResultStr[(p - i) - 1]) xor
                                     Byte(ResultStr[i]));
      ResultStr[i] := Char(Byte(ResultStr[i]) xor
                           Byte(ResultStr[(p - i) - 1]))
    end;
    ResultStr[p] := #0;
    ErrorCode := 0;
  end;
end;




Как преобразовать цвет в оттенки серого


Как преобразовать цвет в оттенки серого



Следущий пример показывает, как преобразовать RGB цвет в аналогичный оттенок серого, наподобие того, как это делает чёрно-белый телевизор:

function RgbToGray(RGBColor : TColor) : TColor;
var
  Gray : byte;
begin
  Gray := Round((0.30 * GetRValue(RGBColor)) +
                (0.59 * GetGValue(RGBColor)) +
                (0.11 * GetBValue(RGBColor )));
  Result := RGB(Gray, Gray, Gray);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Shape1.Brush.Color := RGB(255, 64, 64);
  Shape2.Brush.Color := RgbToGray(Shape1.Brush.Color);
end;

Взято с Исходников.ru



Как преобразовать цвета RGB в CMYK и обратно


Как преобразовать цвета RGB в CMYK и обратно




The following functions RGBTOCMYK() and CMYKTORGB()
demonstrate how to convert between RGB and CMYK color
spaces. Note: There is a direct relationship between RGB
colors and CMY colors. In a CMY color, black tones are
achieved by printing equal amounts of Cyan, Magenta, and
Yellow ink. The black component in a CMY color is achieved
by reducing the CMY components by the minimum of (C, M,
and Y) and substituting pure black in its place producing a
sharper print and using less ink. Since it is possible for a user
to boost the C,M and Y components where boosting the black
component would have been preferable, a ColorCorrectCMYK()
function is provided to achieve the same color by reducing the
C, M and Y components, and boosting the K component.

Example:

procedure RGBTOCMYK(R : byte;
                   G : byte;
                   B : byte;
                   var C : byte;
                   var M : byte;
                   var Y : byte;
                   var K : byte);
begin
 C := 255 - R;
 M := 255 - G;
 Y := 255 - B;
 if C < M then
   K := C else
   K := M;
 if Y < K then
   K := Y;
 if k > 0 then begin
   c := c - k;
   m := m - k;
   y := y - k;
 end;
end;

procedure CMYKTORGB(C : byte;
                   M: byte;
                   Y : byte;
                   K : byte;
                   var R : byte;
                   var G : byte;
                   var B : byte);
begin
  if (Integer(C) + Integer(K)) < 255 then
    R := 255 - (C + K) else
    R := 0;
  if (Integer(M) + Integer(K)) < 255 then
    G := 255 - (M + K) else
    G := 0;
  if (Integer(Y) + Integer(K)) < 255 then
    B := 255 - (Y + K) else
    B := 0;
end;

procedure ColorCorrectCMYK(var C : byte;
                          var M : byte;
                          var Y : byte;
                          var K : byte);
var
 MinColor : byte;
begin
 if C < M then
   MinColor := C else
   MinColor := M;
 if Y < MinColor  then
   MinColor := Y;
 if MinColor + K > 255 then
   MinColor := 255 - K;
 C := C - MinColor;
 M := M - MinColor;
 Y := Y - MinColor;
 K := K + MinColor;
end;

Автор: p0s0l



Как преобразовать длинный IP адрес в короткий адрес / порт ?


Как преобразовать длинный IP адрес в короткий адрес / порт ?



Некоторые старые internet протоколы ( такие как FTP ) посылают IP адреса и номера портов в шестизначном формате XXX.XXX.XXX.XXX.XX.XXX Следующий код позволяет преобразовать такой адрес к нормальному четырёхзначному IP адресу.

procedure LongIPToShort(aLongIPAddress: string; out ShortIPAddress: string; out PortNumber: Integer);
var I, DotPos, tempPort: Integer;
var tempAddy, temp: string;
var TempStr: string;
begin
  tempAddy := '';
  tempStr := '';
// Определяем, какой символ использует отправитель в качестве разделителя длинного IP: , или .

  if (POS(',', aLongIPAddress) <> 0) then
    TempStr := ','
  else
    TempStr := '.';

  for I := 1 to 4 do
    begin
      DotPOS := POS(TempStr, aLongIPAddress);
      tempAddy := tempAddy + (Copy(aLongIPAddress, 1, (DotPos - 1)));
      if I <> 4 then TempADdy := TempAddy + '.';
      Delete(aLongIpAddress, 1, DotPos);
    end;
  DotPos := Pos(TempStr, aLongIpAddress);
  temp := Copy(aLongIpAddress, 1, (DotPos - 1));
  tempPort := (StrToInt(temp) * 256);
  Delete(aLongIpAddress, 1, DotPos);
  TempPort := tempPort + StrToInt(ALongIpAddress);
  ShortIPAddress := TempADdy;
  PortNumber := tempPort;
end;

Взято с Исходников.ru





Как преобразовать http://192.168.1.2 в http://3232235778 ?


Как преобразовать http://192.168.1.2 в http://3232235778 ?



Автор: Roni Havas

Функция, представленная в этом примере может быть и не очень элегантна, зато работает. Функция получает в качестве параметра строку, содержащую IP адрес, и возвращает строку с IP адресом в виде DWord значения. Результат легко можно проверить командой "Ping".

Совместимость: Delphi (все версии)

Обратите внимание, что необходимо добавить "Math" в "Uses" для функции "IntPower";


function IP2HEX(OrgIP: string): string;
var OrgVal: string; // Сохраняем оригинальное значение IP адреса
  O1, O2, O3, O4: string; // части оригинального IP
  H1, H2, H3, H4: string; // шестнадцатиричные части
  HexIP: string; // Здесь будут собраны все шестнадцатиричные части
  XN: array[1..8] of Extended;
  Flt1: Extended;
  Xc: Integer;
begin

// Сохраняем в обратном порядке для простого случая
  Xn[8] := IntPower(16, 0); Xn[7] := IntPower(16, 1); Xn[6] := IntPower(16, 2); Xn[5] := IntPower(16, 3);
  Xn[4] := IntPower(16, 4); Xn[3] := IntPower(16, 5); Xn[2] := IntPower(16, 6); Xn[1] := IntPower(16, 7);

// Сохраняем оригинальный IP адрес
  OrgVal := OrgIP;
  O1 := Copy(OrgVal, 1, Pos('.', OrgVal) - 1); Delete(OrgVal, 1, Pos('.', OrgVal));
  O2 := Copy(OrgVal, 1, Pos('.', OrgVal) - 1); Delete(OrgVal, 1, Pos('.', OrgVal));
  O3 := Copy(OrgVal, 1, Pos('.', OrgVal) - 1); Delete(OrgVal, 1, Pos('.', OrgVal));
  O4 := OrgVal;

  H1 := IntToHex(StrToInt(O1), 2); H2 := IntToHex(StrToInt(O2), 2);
  H3 := IntToHex(StrToInt(O3), 2); H4 := IntToHex(StrToInt(O4), 2);

// Получаем шестнадцатиричное значение IP адреса
  HexIP := H1 + H2 + H3 + H4;

// Преобразуем это большое шестнадцатиричное значение в переменную Float
  Flt1 := 0;
  for Xc := 1 to 8 do
    begin
      case HexIP[Xc] of
        '0'..'9': Flt1 := Flt1 + (StrToInt(HexIP[XC]) * Xn[Xc]);
        'A': Flt1 := Flt1 + (10 * Xn[Xc]);
        'B': Flt1 := Flt1 + (11 * Xn[Xc]);
        'C': Flt1 := Flt1 + (12 * Xn[Xc]);
        'D': Flt1 := Flt1 + (13 * Xn[Xc]);
        'E': Flt1 := Flt1 + (14 * Xn[Xc]);
        'F': Flt1 := Flt1 + (15 * Xn[Xc]);
      end;
    end;
  Result := FloatToStr(Flt1);
end;

Взято с Исходников.ru





Как преобразовать шестнадцатиричный цвет HTML в TColor


Как преобразовать шестнадцатиричный цвет HTML в TColor




unitcolours;

interface
uses
  Windows, Sysutils, Graphics;

  function ConvertHtmlHexToTColor(Color: string):TColor ;
  function CheckHexForHash(col: string):string ;

implementation


function ConvertHtmlHexToTColor(Color: string):TColor ;
var
  rColor: TColor;
begin
  Color := CheckHexForHash(Color);

  if (length(color) >= 6) then
  begin
    {незабудьте, что TColor это bgr, а не rgb: поэтому необходимо изменить порядок}
    color := '$00' + copy(color,5,2) + copy(color,3,2) + copy(color,1,2);
    rColor := StrToInt(color);
  end;

  result := rColor;
end;


// Просто проверяет первый сивол строки на наличие '#' и удаляет его, если он найден
function CheckHexForHash(col: string):string ;
begin
  if col[1] = '#' then
    col := StringReplace(col,'#','',[rfReplaceAll]);
  result := col;
end;

end.

Взято из





Как преобразовать String в Binary и наоборот?


Как преобразовать String в Binary и наоборот?



Автор: Rem



functionBinStrToByte(a_sBinStr: string): byte;
var
 i: integer;
begin
 Result := 0;
 for i := 1 to length(a_sBinStr) do
   Result := (Result shl 1) or byte(a_sBinStr[i] = '1');
end;

function ByteToBinStr(a_bByte: byte): string;
var
 i: integer;
begin
 SetLength(Result, 8);
 for i := 8 downto 1 do
 begin
   Result[i] := chr($30 + (a_bByte and 1));
   a_bByte := a_bByte shr 1;
 end;
end;

// Примечание: вторая функция использует тот факт,
// что в таблице ANSI коды '0' = $30 и '1' = $31



Взято с





Как преобразовать строку в дату?


Как преобразовать строку в дату?



Функция StrToDate преобразует только числа, поэтому, если у Вас месяцы в виде имён, то прийдётся использовать VarToDateTime.

var
D1, D2, D3 : TDateTime;
begin
D1 := VarToDateTime('December 6, 1969');  
D2 := VarToDateTime('6-Apr-1998');  
D3 := VarToDateTime('1998-Apr-6');  
ShowMessage(DateToStr(D1)+' '+DateToStr(D2)+' '+  
DateToStr(D3));  
end;

Взято с Исходников.ru


When extracting data from text or other operating systems the format of date strings can vary dramatically. Borland function StrToDateTime() converts a string to a TDateTime value, but it is limited to the fact that the string parameter must be in the format of the current locale's date/time format.

eg. "MM/DD/YY HH:MM:SS"

Answer:

This is of little use when extracting dates such as ..

   1) "Friday 18 October 2002 08:34am (45 secs)" or "Wednesday 15 May 2002 06:12 (22 secs)"
   2) "20020431"
   3) "12.Nov.03"
   4) "14 Hour 31 Minute 25 Second 321 MSecs"

This function will evaluate a DateTime string in accordance to the DateTime specifier format string supplied. The following specifiers are supported ...

dd             the day as a number with a leading zero or space (01-31).
ddd          the day as an abbreviation (Sun-Sat)
dddd          the day as a full name (Sunday-Saturday)
mm

the month as a number with a leading zero or space (01-12).
mmm

      the month as an abbreviation (Jan-Dec)
mmmm       the month as a full name (January-December)
yy

the year as a two-digit number (00-99).
yyyy

   

      the year as a four-digit number (0000-9999).
hh

the hour with a leading zero or space (00-23)
nn

            the minute with a leading zero or space (00-59).
ss

the second with a leading zero or space (00-59).
zzz

            the millisecond with a leading zero (000-999).
ampm

Specifies am or pm flag hours (0..12)
ap             Specifies a or p flag hours (0..12)
(Any other character corresponds to a literal or delimiter.)

NOTE : One assumption I have to make is that DAYS, MONTHS, HOURS and MINUTES have a leading ZERO or SPACE (ie. are 2 chars long) and MILLISECONDS are 3 chars long (ZERO or SPACE padded)

Using function
DateTimeStrEval(const DateTimeFormat : string; const DateTimeStr : string) : TDateTime;

The above Examples (1..4) can be evaluated as ... (Assume DT1 to DT4 equals example strings 1..4)

   1)

MyDate := DateTimeStrEval('dddd dd mmmm yyyy hh:nnampm (ss xxxx)', DT1);

2)

MyDate := DateTimeStrEval('yyyymmdd', DT2);

3)

MyDate := DateTimeStrEval('dd-mmm-yy', DT3);

4)

MyDate := DateTimeStrEval('hh xxxx nn xxxxxx ss xxxxxx zzz xxxxx', DT4);

uses SysUtils, DateUtils

  // =============================================================================
  // Evaluate a date time string into a TDateTime obeying the
  // rules of the specified DateTimeFormat string
  // eg. DateTimeStrEval('dd-MMM-yyyy hh:nn','23-May-2002 12:34)
  //
  // Delphi 6 Specific in DateUtils can be translated to ....
  //
  // YearOf()
  //
  // function YearOf(const AValue: TDateTime): Word;
  // var LMonth, LDay : word;
  // begin
  //   DecodeDate(AValue,Result,LMonth,LDay);
  // end;
  //
  // TryEncodeDateTime()
  //
  // function TryEncodeDateTime(const AYear,AMonth,ADay,AHour,AMinute,ASecond,
  //                            AMilliSecond : word;
  //                            out AValue : TDateTime): Boolean;
  // var LTime : TDateTime;
  // begin
  //   Result := TryEncodeDate(AYear, AMonth, ADay, AValue);
  //   if Result then begin
  //     Result := TryEncodeTime(AHour, AMinute, ASecond, AMilliSecond, LTime);
  //     if Result then
  //        AValue := AValue + LTime;
  //   end;
  // end;
  //
  // (TryEncodeDate() and TryEncodeTime() is the same as EncodeDate() and
  //  EncodeTime() with error checking and boolean return value)
  //
  // =============================================================================

function DateTimeStrEval(const DateTimeFormat: string;
  const DateTimeStr: string): TDateTime;
var
  i, ii, iii: integer;
  Retvar: TDateTime;
  Tmp,
    Fmt, Data, Mask, Spec: string;
  Year, Month, Day, Hour,
    Minute, Second, MSec: word;
  AmPm: integer;
begin
  Year := 1;
  Month := 1;
  Day := 1;
  Hour := 0;
  Minute := 0;
  Second := 0;
  MSec := 0;
  Fmt := UpperCase(DateTimeFormat);
  Data := UpperCase(DateTimeStr);
  i := 1;
  Mask := '';
  AmPm := 0;

  while i < length(Fmt) do
  begin
    if Fmt[i] in ['A', 'P', 'D', 'M', 'Y', 'H', 'N', 'S', 'Z'] then
    begin
      // Start of a date specifier
      Mask := Fmt[i];
      ii := i + 1;

      // Keep going till not valid specifier
      while true do
      begin
        if ii > length(Fmt) then
          Break; // End of specifier string
        Spec := Mask + Fmt[ii];

        if (Spec = 'DD') or (Spec = 'DDD') or (Spec = 'DDDD') or
          (Spec = 'MM') or (Spec = 'MMM') or (Spec = 'MMMM') or
          (Spec = 'YY') or (Spec = 'YYY') or (Spec = 'YYYY') or
          (Spec = 'HH') or (Spec = 'NN') or (Spec = 'SS') or
          (Spec = 'ZZ') or (Spec = 'ZZZ') or
          (Spec = 'AP') or (Spec = 'AM') or (Spec = 'AMP') or
          (Spec = 'AMPM') then
        begin
          Mask := Spec;
          inc(ii);
        end
        else
        begin
          // End of or Invalid specifier
          Break;
        end;
      end;

      // Got a valid specifier ? - evaluate it from data string
      if (Mask <> '') and (length(Data) > 0) then
      begin
        // Day 1..31
        if (Mask = 'DD') then
        begin
          Day := StrToIntDef(trim(copy(Data, 1, 2)), 0);
          delete(Data, 1, 2);
        end;

        // Day Sun..Sat (Just remove from data string)
        if Mask = 'DDD' then
          delete(Data, 1, 3);

        // Day Sunday..Saturday (Just remove from data string LEN)
        if Mask = 'DDDD' then
        begin
          Tmp := copy(Data, 1, 3);
          for iii := 1 to 7 do
          begin
            if Tmp = Uppercase(copy(LongDayNames[iii], 1, 3)) then
            begin
              delete(Data, 1, length(LongDayNames[iii]));
              Break;
            end;
          end;
        end;

        // Month 1..12
        if (Mask = 'MM') then
        begin
          Month := StrToIntDef(trim(copy(Data, 1, 2)), 0);
          delete(Data, 1, 2);
        end;

        // Month Jan..Dec
        if Mask = 'MMM' then
        begin
          Tmp := copy(Data, 1, 3);
          for iii := 1 to 12 do
          begin
            if Tmp = Uppercase(copy(LongMonthNames[iii], 1, 3)) then
            begin
              Month := iii;
              delete(Data, 1, 3);
              Break;
            end;
          end;
        end;

        // Month January..December
        if Mask = 'MMMM' then
        begin
          Tmp := copy(Data, 1, 3);
          for iii := 1 to 12 do
          begin
            if Tmp = Uppercase(copy(LongMonthNames[iii], 1, 3)) then
            begin
              Month := iii;
              delete(Data, 1, length(LongMonthNames[iii]));
              Break;
            end;
          end;
        end;

        // Year 2 Digit
        if Mask = 'YY' then
        begin
          Year := StrToIntDef(copy(Data, 1, 2), 0);
          delete(Data, 1, 2);
          if Year < TwoDigitYearCenturyWindow then
            Year := (YearOf(Date) div 100) * 100 + Year
          else
            Year := (YearOf(Date) div 100 - 1) * 100 + Year;
        end;

        // Year 4 Digit
        if Mask = 'YYYY' then
        begin
          Year := StrToIntDef(copy(Data, 1, 4), 0);
          delete(Data, 1, 4);
        end;

        // Hours
        if Mask = 'HH' then
        begin
          Hour := StrToIntDef(trim(copy(Data, 1, 2)), 0);
          delete(Data, 1, 2);
        end;

        // Minutes
        if Mask = 'NN' then
        begin
          Minute := StrToIntDef(trim(copy(Data, 1, 2)), 0);
          delete(Data, 1, 2);
        end;

        // Seconds
        if Mask = 'SS' then
        begin
          Second := StrToIntDef(trim(copy(Data, 1, 2)), 0);
          delete(Data, 1, 2);
        end;

        // Milliseconds
        if (Mask = 'ZZ') or (Mask = 'ZZZ') then
        begin
          MSec := StrToIntDef(trim(copy(Data, 1, 3)), 0);
          delete(Data, 1, 3);
        end;

        // AmPm A or P flag
        if (Mask = 'AP') then
        begin
          if Data[1] = 'A' then
            AmPm := -1
          else
            AmPm := 1;
          delete(Data, 1, 1);
        end;

        // AmPm AM or PM flag
        if (Mask = 'AM') or (Mask = 'AMP') or (Mask = 'AMPM') then
        begin
          if copy(Data, 1, 2) = 'AM' then
            AmPm := -1
          else
            AmPm := 1;
          delete(Data, 1, 2);
        end;

        Mask := '';
        i := ii;
      end;
    end
    else
    begin
      // Remove delimiter from data string
      if length(Data) > 1 then
        delete(Data, 1, 1);
      inc(i);
    end;
  end;

  if AmPm = 1 then
    Hour := Hour + 12;
  if not TryEncodeDateTime(Year, Month, Day, Hour, Minute, Second, MSec, Retvar) then
    Retvar := 0.0;
  Result := Retvar;
end;

Взято с

Delphi Knowledge Base






Как преобразовать текст в иконку?


Как преобразовать текст в иконку?





unit unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Timer1: TTimer;
    Image1: TImage;
    procedure Button1Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    function StringToIcon(const st: string): HIcon;
  public
{ Public declarations }
  end;

var
  Form1: TForm1;
  sss: Integer = 0;

implementation

{$R *.DFM}

type
  ICONIMAGE = record
    Width, Height, Colors: DWORD; // Ширина, Высота и кол-во цветов
    lpBits: PChar; // указатель на DIB биты
    dwNumBytes: DWORD; // Сколько байт?
    lpbi: PBitmapInfoHeader; // указатель на заголовок
    lpXOR: PChar; // указатель на XOR биты изображения
    lpAND: PChar; // указатель на AND биты изображения
  end;

function CopyColorTable(var lpTarget: BITMAPINFO; const lpSource:
  BITMAPINFO): boolean;
var
  dc: HDC;
  hPal: HPALETTE;
  pe: array[0..255] of PALETTEENTRY;
  i: Integer;
begin
  result := False;
  case (lpTarget.bmiHeader.biBitCount) of
    8:
      if lpSource.bmiHeader.biBitCount = 8 then
        begin
          Move(lpSource.bmiColors, lpTarget.bmiColors, 256 * sizeof(RGBQUAD));
          result := True
        end
      else
        begin
          dc := GetDC(0);
          if dc <> 0 then
          try
            hPal := CreateHalftonePalette(dc);
            if hPal <> 0 then
            try
              if GetPaletteEntries(hPal, 0, 256, pe) <> 0 then
                begin
                  for i := 0 to 255 do
                    begin
                      lpTarget.bmiColors[i].rgbRed := pe[i].peRed;
                      lpTarget.bmiColors[i].rgbGreen := pe[i].peGreen;
                      lpTarget.bmiColors[i].rgbBlue := pe[i].peBlue;
                      lpTarget.bmiColors[i].rgbReserved := pe[i].peFlags
                    end;
                  result := True
                end
            finally
              DeleteObject(hPal)
            end
          finally
            ReleaseDC(0, dc)
          end
        end;

    4:
      if lpSource.bmiHeader.biBitCount = 4 then
        begin
          Move(lpSource.bmiColors, lpTarget.bmiColors, 16 * sizeof(RGBQUAD));
          result := True
        end
      else
        begin
          hPal := GetStockObject(DEFAULT_PALETTE);
          if (hPal <> 0) and (GetPaletteEntries(hPal, 0, 16, pe) <> 0) then
            begin
              for i := 0 to 15 do
                begin
                  lpTarget.bmiColors[i].rgbRed := pe[i].peRed;
                  lpTarget.bmiColors[i].rgbGreen := pe[i].peGreen;
                  lpTarget.bmiColors[i].rgbBlue := pe[i].peBlue;
                  lpTarget.bmiColors[i].rgbReserved := pe[i].peFlags
                end;
              result := True
            end
        end;
    1:
      begin
        i := 0;
        lpTarget.bmiColors[i].rgbRed := 0;
        lpTarget.bmiColors[i].rgbGreen := 0;
        lpTarget.bmiColors[i].rgbBlue := 0;
        lpTarget.bmiColors[i].rgbReserved := 0;
        i := 1;
        lpTarget.bmiColors[i].rgbRed := 255;
        lpTarget.bmiColors[i].rgbGreen := 255;
        lpTarget.bmiColors[i].rgbBlue := 255;
        lpTarget.bmiColors[i].rgbReserved := 0;
        result := True
      end;
  else
    result := True
  end
end;

function WidthBytes(bits: DWORD): DWORD;
begin
  result := ((bits + 31) shr 5) shl 2
end;

function BytesPerLine(const bmih: BITMAPINFOHEADER): DWORD;
begin
  result := WidthBytes(bmih.biWidth * bmih.biPlanes * bmih.biBitCount)
end;

function DIBNumColors(const lpbi: BitmapInfoHeader): word;
var
  dwClrUsed: DWORD;
begin
  dwClrUsed := lpbi.biClrUsed;
  if dwClrUsed <> 0 then
    result := Word(dwClrUsed)
  else
    case lpbi.biBitCount of
      1: result := 2;
      4: result := 16;
      8: result := 256
    else
      result := 0
    end
end;

function PaletteSize(const lpbi: BitmapInfoHeader): word;
begin
  result := DIBNumColors(lpbi) * sizeof(RGBQUAD)
end;

function FindDIBBits(const lpbi: BitmapInfo): PChar;
begin
  result := @lpbi;
  result := result + lpbi.bmiHeader.biSize + PaletteSize(lpbi.bmiHeader)
end;

function ConvertDIBFormat(var lpSrcDIB: BITMAPINFO; nWidth, nHeight, nbpp: DWORD; bStretch: boolean):
  PBitmapInfo;
var
  lpbmi: PBITMAPINFO;
  lpSourceBits, lpTargetBits: Pointer;
  DC, hSourceDC, hTargetDC: HDC;
  hSourceBitmap, hTargetBitmap, hOldTargetBitmap, hOldSourceBitmap:
  HBITMAP;
  dwSourceBitsSize, dwTargetBitsSize, dwTargetHeaderSize: DWORD;
begin
  result := nil;
// Располагаем и заполняем структуру BITMAPINFO для нового DIB
// Обеспе?иваем достато?но места для 256-цветной таблицы
  dwTargetHeaderSize := sizeof(BITMAPINFO) + (256 * sizeof(RGBQUAD));
  GetMem(lpbmi, dwTargetHeaderSize);
  try
    lpbmi^.bmiHeader.biSize := sizeof(BITMAPINFOHEADER);
    lpbmi^.bmiHeader.biWidth := nWidth;
    lpbmi^.bmiHeader.biHeight := nHeight;
    lpbmi^.bmiHeader.biPlanes := 1;
    lpbmi^.bmiHeader.biBitCount := nbpp;
    lpbmi^.bmiHeader.biCompression := BI_RGB;
    lpbmi^.bmiHeader.biSizeImage := 0;
    lpbmi^.bmiHeader.biXPelsPerMeter := 0;
    lpbmi^.bmiHeader.biYPelsPerMeter := 0;
    lpbmi^.bmiHeader.biClrUsed := 0;
    lpbmi^.bmiHeader.biClrImportant := 0; // Заполняем в таблице цветов
    if CopyColorTable(lpbmi^, lpSrcDIB) then
      begin
        DC := GetDC(0);
        hTargetBitmap := CreateDIBSection(DC, lpbmi^, DIB_RGB_COLORS,
          lpTargetBits, 0, 0);
        hSourceBitmap := CreateDIBSection(DC, lpSrcDIB, DIB_RGB_COLORS,
          lpSourceBits, 0, 0);

        try
          if (dc <> 0) and (hTargetBitmap <> 0) and (hSourceBitmap <> 0) then
            begin
              hSourceDC := CreateCompatibleDC(DC);
              hTargetDC := CreateCompatibleDC(DC);
              try
                if (hSourceDC <> 0) and (hTargetDC <> 0) then
                  begin
// Flip the bits on the source DIBSection to match the source DIB
                    dwSourceBitsSize := DWORD(lpSrcDIB.bmiHeader.biHeight) * BytesPerLine(lpSrcDIB.bmiHeader);
                    dwTargetBitsSize := DWORD(lpbmi^.bmiHeader.biHeight) *
                      BytesPerLine(lpbmi^.bmiHeader);
                    Move(FindDIBBits(lpSrcDIB)^, lpSourceBits^, dwSourceBitsSize);

// Select DIBSections into DCs
                    hOldSourceBitmap := SelectObject(hSourceDC, hSourceBitmap);
                    hOldTargetBitmap := SelectObject(hTargetDC, hTargetBitmap);

                    try
                      if (hOldSourceBitmap <> 0) and (hOldTargetBitmap <> 0) then
                        begin
// Устанавливаем таблицу цветов для DIBSections
                          if lpSrcDIB.bmiHeader.biBitCount <= 8 then
                            SetDIBColorTable(hSourceDC, 0, 1 shl lpSrcDIB.bmiHeader.biBitCount, lpSrcDIB.bmiColors);

                          if lpbmi^.bmiHeader.biBitCount <= 8 then
                            SetDIBColorTable(hTargetDC, 0, 1 shl
                              lpbmi^.bmiHeader.biBitCount, lpbmi^.bmiColors);

// If we are asking for a straight copy, do it
                          if (lpSrcDIB.bmiHeader.biWidth = lpbmi^.bmiHeader.biWidth) and (lpSrcDIB.bmiHeader.biHeight = lpbmi^.bmiHeader.biHeight) then
                            BitBlt(hTargetDC, 0, 0, lpbmi^.bmiHeader.biWidth, lpbmi^.bmiHeader.biHeight, hSourceDC, 0, 0, SRCCOPY)
                          else if bStretch then
                            begin
                              SetStretchBltMode(hTargetDC, COLORONCOLOR);
                              StretchBlt(hTargetDC, 0, 0, lpbmi^.bmiHeader.biWidth,
                                lpbmi^.bmiHeader.biHeight,
                                hSourceDC, 0, 0, lpSrcDIB.bmiHeader.biWidth, lpSrcDIB.bmiHeader.biHeight,
                                SRCCOPY)
                            end
                          else
                            BitBlt(hTargetDC, 0, 0, lpbmi^.bmiHeader.biWidth, lpbmi^.bmiHeader.biHeight, hSourceDC, 0, 0, SRCCOPY);

                          GDIFlush;
                          GetMem(result, Integer(dwTargetHeaderSize + dwTargetBitsSize));

                          Move(lpbmi^, result^, dwTargetHeaderSize);
                          Move(lpTargetBits^, FindDIBBits(result^)^, dwTargetBitsSize)
                        end
                    finally
                      if hOldSourceBitmap <> 0 then SelectObject(hSourceDC, hOldSourceBitmap);
                      if hOldTargetBitmap <> 0 then SelectObject(hTargetDC, hOldTargetBitmap);
                    end
                  end
              finally
                if hSourceDC <> 0 then DeleteDC(hSourceDC);
                if hTargetDC <> 0 then
                  DeleteDC(hTargetDC)
              end
            end;
        finally
          if hTargetBitmap <> 0 then DeleteObject(hTargetBitmap);
          if hSourceBitmap <> 0 then DeleteObject(hSourceBitmap);
          if dc <> 0 then
            ReleaseDC(0, dc)
        end
      end
  finally
    FreeMem(lpbmi)
  end
end;

function DIBToIconImage(var lpii: ICONIMAGE; var lpDIB: BitmapInfo;
  bStretch: boolean): boolean;
var
  lpNewDIB: PBitmapInfo;
begin
  result := False;
  lpNewDIB := ConvertDIBFormat(lpDIB, lpii.Width, lpii.Height, lpii.Colors,
    bStretch);
  if Assigned(lpNewDIB) then
  try

    lpii.dwNumBytes := sizeof(BITMAPINFOHEADER) // Заголовок
      + PaletteSize(lpNewDIB^.bmiHeader) // Палитра
      + lpii.Height * BytesPerLine(lpNewDIB^.bmiHeader) // XOR маска
      + lpii.Height * WIDTHBYTES(lpii.Width); // AND маска
// Если здесь уже картинка, то освобождаем е?
    if lpii.lpBits <> nil then
      FreeMem(lpii.lpBits);

    GetMem(lpii.lpBits, lpii.dwNumBytes);
    Move(lpNewDib^, lpii.lpBits^, sizeof(BITMAPINFOHEADER) + PaletteSize
      (lpNewDIB^.bmiHeader));
// Выравниваем внутренние указатели/переменные для новой картинки
    lpii.lpbi := PBITMAPINFOHEADER(lpii.lpBits);
    lpii.lpbi^.biHeight := lpii.lpbi^.biHeight * 2;

    lpii.lpXOR := FindDIBBits(PBitmapInfo(lpii.lpbi)^);
    Move(FindDIBBits(lpNewDIB^)^, lpii.lpXOR^, lpii.Height * BytesPerLine
      (lpNewDIB^.bmiHeader));

    lpii.lpAND := lpii.lpXOR + lpii.Height * BytesPerLine
      (lpNewDIB^.bmiHeader);
    Fillchar(lpii.lpAnd^, lpii.Height * WIDTHBYTES(lpii.Width), $00);

    result := True
  finally
    FreeMem(lpNewDIB)
  end
end;

function TForm1.StringToIcon(const st: string): HIcon;
var
  memDC: HDC;
  bmp: HBITMAP;
  oldObj: HGDIOBJ;
  rect: TRect;
  size: TSize;
  infoHeaderSize: DWORD;
  imageSize: DWORD;
  infoHeader: PBitmapInfo;
  icon: IconImage;
  oldFont: HFONT;

begin
  result := 0;
  memDC := CreateCompatibleDC(0);
  if memDC <> 0 then
  try
    bmp := CreateCompatibleBitmap(Canvas.Handle, 16, 16);
    if bmp <> 0 then
    try
      oldObj := SelectObject(memDC, bmp);
      if oldObj <> 0 then
      try
        rect.Left := 0;
        rect.top := 0;
        rect.Right := 16;
        rect.Bottom := 16;
        SetTextColor(memDC, RGB(255, 0, 0));
        SetBkColor(memDC, RGB(128, 128, 128));
        oldFont := SelectObject(memDC, font.Handle);
        GetTextExtentPoint32(memDC, PChar(st), Length(st), size);
        ExtTextOut(memDC, (rect.Right - size.cx) div 2, (rect.Bottom - size.cy) div 2, ETO_OPAQUE, @rect, PChar(st), Length(st), nil);
        SelectObject(memDC, oldFont);
        GDIFlush;

        GetDibSizes(bmp, infoHeaderSize, imageSize);
        GetMem(infoHeader, infoHeaderSize + ImageSize);
        try
          GetDib(bmp, SystemPalette16, infoHeader^, PChar(DWORD(infoHeader) + infoHeaderSize)^);

          icon.Colors := 4;
          icon.Width := 32;
          icon.Height := 32;
          icon.lpBits := nil;
          if DibToIconImage(icon, infoHeader^, True) then
          try
            result := CreateIconFromResource(PByte(icon.lpBits), icon.dwNumBytes, True, $00030000);
          finally
            FreeMem(icon.lpBits)
          end
        finally
          FreeMem(infoHeader)
        end

      finally
        SelectObject(memDC, oldOBJ)
      end
    finally
      DeleteObject(bmp)
    end
  finally
    DeleteDC(memDC)
  end
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Application.Icon.Handle := StringToIcon('0');
  Timer1.Enabled := True;
  Button1.Enabled := False;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Inc(sss);
  if sss > 100 then sss := 1;
  Application.Icon.Handle := StringToIcon(IntToStr(sss));
end;

end.

Автор ответа: Baa
Взято с Vingrad.ru




Как преобразовать указатель на метод в указатель на функцию?


Как преобразовать указатель на метод в указатель на функцию?





// Converting method pointers into function pointers 

// Often you need a function pointer for a callback function. But what, if you want to specify a method as 
// an callback? Converting a method pointer to a function pointer is not a trivial task; both types are 
// incomatible with each other. Although you have the possibility to convert like this "@TClass.SomeMethod", 
// this is more a hack than a solution, because it restricts the use of this method to some kind of a class 
// function, where you cannot access instance variables. If you fail to do so, you'll get a wonderful gpf. 
// But there is a better solution: run time code generation! Just allocate an executeable memory block, and 
// write 4 machine code instructions into it: 2 instructions loads the two pointers of the method pointer 
// (code & data) into the registers, one calls the method via the code pointer, and the last is just a return 
// Now you can use this pointer to the allocated memory as a plain funtion pointer, but in fact you are 
// calling a method for a specific instance of a Class. 



type TMyMethod = procedure of object; 


function MakeProcInstance(M: TMethod): Pointer; 
begin 
  // allocate memory 
  GetMem(Result, 15); 
  asm 
    // MOV ECX,  
    MOV BYTE PTR [EAX], $B9 
    MOV ECX, M.Data 
    MOV DWORD PTR [EAX+$1], ECX 
    // POP EDX 
    MOV BYTE PTR [EAX+$5], $5A 
    // PUSH ECX 
    MOV BYTE PTR [EAX+$6], $51 
    // PUSH EDX 
    MOV BYTE PTR [EAX+$7], $52 
    // MOV ECX,  
    MOV BYTE PTR [EAX+$8], $B9 
    MOV ECX, M.Code 
    MOV DWORD PTR [EAX+$9], ECX 
    // JMP ECX 
    MOV BYTE PTR [EAX+$D], $FF 
    MOV BYTE PTR [EAX+$E], $E1 
  end; 
end; 


procedure FreeProcInstance(ProcInstance: Pointer); 
begin 
  // free memory 
  FreeMem(ProcInstance, 15); 
end; 

Взято с сайта



Как прервать печать и заставить печатать свой файл?


Как прервать печать и заставить печатать свой файл?





uses
printers;

{$R *.DFM}

procedure StartPrintToFile(filename: string);
var
  CTitle: array[0..31] of Char;
  DocInfo: TDocInfo;
begin
  with Printer do
  begin
    BeginDoc;
    { Abort job just started on API level. }
    EndPage(Canvas.handle);
    Windows.AbortDoc(Canvas.handle);
    { Restart it with a print file as destination. }
    StrPLCopy(CTitle, Title, SizeOf(CTitle) - 1);
    FillChar(DocInfo, SizeOf(DocInfo), 0);
    with DocInfo do
    begin
      cbSize := SizeOf(DocInfo);
      lpszDocName := CTitle;
      lpszOutput := PChar(filename);
    end;
    StartDoc(Canvas.handle, DocInfo);
    StartPage(Canvas.handle);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  StartPrintToFile('C:\temp\temp.prn');
  try
    Printer.Canvas.TextOut(100, 100, 'Hello World.');
  finally
    Printer.endDoc;
  end;
end;

Взято с

Delphi Knowledge Base






Как при выполнении долгой операции в Oracle показать прогресс бар?


Как при выполнении долгой операции в Oracle показать прогресс бар?



Автор: Philip A. Milovanov ( http://korys.chat.ru )

Ниже приведен пример, как это сделать при помощи Direct Oracle Access, надеюсь этот кусок кода несложно запустить в отдельном процессе, а в другом можно запустить перемесчатель прогресс бара. Есть готовая компонента, могу поделиться.

//на создании потока вставим то, что будет выбирать необходимую информацию

Self.fods.SQL.Text:='SELECT SOFAR FROM V$SESSION_LONGOPS WHERE CONTEXT=:FK_ID';
Self.fods.DeclareVariable('FK_ID',otInteger);
Self.fods.SetVariable('FK_ID',ID);

//На выполнение потока вешаем открытие/закрытие TOracleDataSet
while (Terminated = false) do
  begin
    Self.fods.Close;
    Self.fods.Open;
    Self.fpb.Progress := Self.fods.FieldByName('SOFAR').AsInteger;
//^^^^Эта строчка как раз и устанавливает нужный прогрессбар в нужную позицию...
  end;


Ну и соответсвенно перед выполнением всего этого дела необходимо выставить максимальное число (100%) :
PROCEDURE SETMaxValue(nVal IN NUMBER); 
Минимальное:
PROCEDURE SETMinValue(nVal IN NUMBER); 
Значение шага:
PROCEDURE SetStepValue(nValue IN NUMBER); 

Вышеприведенный кусок кода - клиентская часть, но есть и "подводный камень" - серверная часть... Данный метотод подкодит только для функций, процедур и пактеов, в которых вы можете написать вставить следущую строчку:
PROGRESS_BAR.STEPIT;

Код пакета PROGRESS_BAR приведен ниже:

create or replace package PROGRESS_BAR 
IS 
-- Wrote by Philip A. Milovanov 
nMaxValue NUMBER:=0; 
nMinValue NUMBER:=0; 
nCurrentValue NUMBER:=0; 
nStepValue NUMBER:=1; 
nID PLS_INTEGER; 
slno PLS_INTEGER; 
target PLS_INTEGER; 
PROCEDURE SETMaxValue(nVal IN NUMBER); 
PROCEDURE SETMinValue(nVal IN NUMBER); 
FUNCTION INIT RETURN NUMBER; 
PROCEDURE StepIt; 
PROCEDURE SetStepValue(nValue IN NUMBER); 
PROCEDURE StepIt(C IN NUMBER);
END; -- Package Specification PROGRESS_BAR 
/
--Сам пакет:
Create or Replace Package Body PROGRESS_BAR 
IS 
-- Wrote by Philip A. Milovanov 
PROCEDURE SETMaxValue(nVal IN NUMBER) IS 
BEGIN 
if nVal<nMinValue THEN 
RAISE_APPLICATION_ERROR(-20001,'&Igrave;&egrave;&iacute;&egrave;&igrave;&agrave;&euml;&uuml;&iacute;&icirc;&aring; &ccedil;&iacute;&agrave;&divide;&aring;&iacute;&egrave;&aring; &iacute;&aring; &auml;&icirc;&euml;&aelig;&iacute;&icirc; &aacute;&ucirc;&ograve;&uuml; &aacute;&icirc;&euml;&uuml;&oslash;&aring; &igrave;&agrave;&ecirc;&ntilde;&egrave;&igrave;&agrave;&euml;&uuml;&iacute;&icirc;&atilde;&icirc; &igrave;&egrave;&iacute;:'nMinValue' ,&igrave;&agrave;&ecirc;&ntilde;:'nVal); 
END IF; 
nMaxValue:=nVal; 
END; 
PROCEDURE SETMinValue(nVal IN NUMBER) IS 
BEGIN 
if nVal>nMaxValue THEN 
RAISE_APPLICATION_ERROR(-20001,'&Igrave;&egrave;&iacute;&egrave;&igrave;&agrave;&euml;&uuml;&iacute;&icirc;&aring; &ccedil;&iacute;&agrave;&divide;&aring;&iacute;&egrave;&aring; &iacute;&aring; &auml;&icirc;&euml;&aelig;&iacute;&icirc; &aacute;&ucirc;&ograve;&uuml; &aacute;&icirc;&euml;&uuml;&oslash;&aring; &igrave;&agrave;&ecirc;&ntilde;&egrave;&igrave;&agrave;&euml;&uuml;&iacute;&icirc;&atilde;&icirc; &igrave;&egrave;&iacute;:'nVal' ,&igrave;&agrave;&ecirc;&ntilde;:'nMaxValue); 
END IF; 
nMinValue:=nVal; 
END; 
FUNCTION INIT RETURN NUMBER IS 
CURSOR c IS SELECT OBJECT_ID FROM ALL_OBJECTS WHERE OBJECT_NAME='PROGRESS_BAR'; 
i NUMBER; 
BEGIN 
OPEN c; 
FETCH c INTO target; 
CLOSE c; 
SELECT SEQ_TPROCESS_BAR.NEXTVAL INTO i FROM DUAL; 
nCurrentValue:=nMinValue; 
nID:=DBMS_APPLICATION_INFO.set_session_longops_nohint; 
DBMS_APPLICATION_INFO.SET_SESSION_LONGOPS(nID,slno,'CALCULATING REPORT',target,i,nCurrentValue,nMaxValue,'PROGRESS BAR INFO',NULL); 
RETURN i; 
END; 
PROCEDURE StepIt IS 
BEGIN 
nCurrentValue:=nCurrentValue+nStepValue; 
DBMS_APPLICATION_INFO.SET_SESSION_LONGOPS(nID,slno,'CALCULATING REPORT',target,nMinValue,nCurrentValue,nMaxValue,'PROGRESS BAR INFO',NULL); 
END; 
PROCEDURE SetStepValue(nValue IN NUMBER) IS 
BEGIN 
nStepValue:=nValue; 
END; 
PROCEDURE StepIt(C IN NUMBER) IS 
BEGIN 
nCurrentValue:=nCurrentValue+c; 
DBMS_APPLICATION_INFO.SET_SESSION_LONGOPS(nID,slno,'CALCULATING REPORT',target,nMinValue,nCurrentValue,nMaxValue,'PROGRESS BAR INFO',NULL); 
END; 
END; 

Взято с Исходников.ru



Как прикрепить свою форму к другому приложению?


Как прикрепить свою форму к другому приложению?



Для этого Вам понадобится переопределить процедуру CreateParams у желаемой формы. А в ней установить params.WndParent в дескриптор окна, к которому Вы хотите прикрепить форму.

... = class(TForm) 
  ... 
  protected 
    procedure CreateParams( var params: TCreateParams ); override; 
... 

procedure TForm2.Createparams(var params: TCreateParams); 
var 
   aHWnd : HWND; 
begin 
  inherited; 
{как-нибудь получаем существующий дескриптор}
  ahWnd := GetForegroundWindow; 
{а теперь:}
  params.WndParent := ahWnd; 
end; 




Взято с Исходников.ru



Как приложение оставить свёрнутым в иконку?


Как приложение оставить свёрнутым в иконку?



Для этого необходимо обработать сообщение WMQUERYOPEN. Однако обработчик сообщения необходимо поместить в секции private - т.е. в объявлении TForm.


procedure WMQueryOpen(var Msg: TWMQueryOpen); message WM_QUERYOPEN; 

Реализация будет выглядеть следующим образом:

procedure WMQueryOpen(var Msg: TWMQueryOpen); 
begin 
  Msg.Result := 0; 
end;





Как приложению воспользоваться своими шрифтами?


Как приложению воспользоваться своими шрифтами?




Может ли кто-нибудь подсказать или решить такую проблему: мне нужно убедиться, что мое приложение использует доступные, а не ближайшие шрифты, установленные пользователем в системе? Я пробовал копировать файл #.ttf в директорию пользователя windows\system, но мое приложение так и не смогло их увидеть и выбрать для дальнейшего использования.

Ниже приведен код для Delphi, который динамически устанавливает шрифты, загружаемые только во время работы приложения. Вы можете расположить файл(ы) шрифтов в каталоге приложения. Они будут инсталлированы при загрузке формы и выгружены при ее разрушении. Вам возможно придется модифицировать код для работы с Delphi 2, поскольку он использует вызовы Windows API, которые могут как измениться, так и нет. Если в коде вы видите "...", то значит в этом месте может располагаться какой-либо код, не относящийся к существу вопроса.

Ну и, конечно, вы должны заменить "MYFONT" на реальное имя файла вашего шрифта.

type
TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    ...
    private
    { Private declarations }
    bLoadedFont: boolean;
  public
    { Public declarations }
  end;

procedure TForm1.FormCreate(Sender: TObject);
var
  sAppDir: string;
  sFontRes: string;
begin
  sAppDir := Application.ExeName;
  sAppDir := copy(sAppDir, 1, rpos('\', sAppDir));

  sFontRes := sAppDir + 'MYFONT.FOT';
  if not FileExists(sFontRes) then
  begin
    sFontRes := sFontRes + #0;
    sFont := sAppDir + 'MYFONT.TTF' + #0;
    CreateScalableFontResource(0, @sFontRes[1], @sFont[1], nil);
  end;

  sFontRes := sAppDir + 'MYFONT.FOT';
  if FileExists(sFontRes) then
  begin
    sFontRes := sFontRes + #0;
    if AddFontResource(@sFontRes[1]) = 0 then
      bLoadedFont := false
    else
    begin
      bLoadedFont := true;
      SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);
    end;
  end;
  ...
end;

procedure TForm1.FormDestroy(Sender: TObject);
var
  sFontRes: string;
begin
  if bLoadedFont then
  begin
    sFontRes := sAppDir + 'MYFONT.FOT' + #0;
    RemoveFontResource(@sFontRes[1]);
    SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);
  end;
end;




Я поработал с данным кодом и внес некоторые поправки для корректной работы на Delphi 2.0. На Delphi 3.0 не испытано.

Электронная справка по продукту InstallShield показывает, что в системах Win95 и WinNT FOT-файл не нужен. Вам нужен только TTF-файл.

В результате процедура FormCreate стала выглядеть так:

var
  sAppDir, sFontRes: string;
begin
  {...другой код...}
  sAppDir := extractfilepath(Application.ExeName);

  sFontRes := sAppDir + 'MYFONT.TTF';
  if FileExists(sFontRes) then
  begin
    sFontRes := sFontRes + #0;
    if AddFontResource(@sFontRes[1]) = 0 then
      bLoadedFont := false
    else
    begin
      bLoadedFont := true;
      SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);
    end;
  end;
  {...}
end; {FormCreate}




А FormDestroy так:



var
  sFontRes, sAppDir: string;
begin
  {...другой код...}

  if bLoadedFont then
  begin
    sAppDir := extractfilepath(Application.ExeName);
    sFontRes := sAppDir + 'MYFONT.TTF' + #0;
    RemoveFontResource(@sFontRes[1]);
    SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);
  end;

  {...другой код...}
end; {FormDestroy}

Для упрощения этого я сделал простую функцию, совмещающую обе этих задачи. Она возвращает логическое значение, говорящая об успехе, или наоборот, о неудаче операции загрузки или выгрузки шрифта.



{1998-01-16 Функция загрузки и выгрузки шрифта.}

function LoadFont(sFontFileName: string; bLoadIt: boolean): boolean;
var
  sFont, sAppDir, sFontRes: string;
begin
  result := TRUE;

  if bLoadIt then
  begin
    {Загрузка шрифта.}
    if FileExists(sFontFileName) then
    begin
      sFontRes := sFontFileName + #0;
      if AddFontResource(@sFontRes[1]) = 0 then
        result := FALSE
      else
        SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);
    end;
  end
  else
  begin
    {Выгрузка шрифта.}
    sFontRes := sFontFileName + #0;
    result := RemoveFontResource(@sFontRes[1]);
    SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);
  end;
end; {LoadFont}



Взято из





Как принимать перетаскиваемые файлы из проводника?


Как принимать перетаскиваемые файлы из проводника?



Вот пример с TListbox на форме:

type 
  TForm1 = class(TForm) 
    ListBox1: TListBox; 
    procedure FormCreate(Sender: TObject); 
  protected 
    procedure WMDROPFILES (var Msg: TMessage); message WM_DROPFILES; 
  private 
  public 
  end; 

var 
  Form1: TForm1; 

implementation 
uses shellapi; 

{$R *.DFM} 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
  DragAcceptFiles(Form1.Handle, true); 
end; 

procedure TForm1.WMDROPFILES (var Msg: TMessage); 
var 
  i, 
  amount, 
  size: integer; 
  Filename: PChar; 
begin 
  inherited; 
  Amount := DragQueryFile(Msg.WParam, $FFFFFFFF, Filename, 255); 
  for i := 0 to (Amount - 1) do 
  begin 
    size := DragQueryFile(Msg.WParam, i , nil, 0) + 1; 
    Filename:= StrAlloc(size); 
    DragQueryFile(Msg.WParam,i , Filename, size); 
    listbox1.items.add(StrPas(Filename)); 
    StrDispose(Filename); 
  end; 
  DragFinish(Msg.WParam); 
end;

Взято с Исходников.ru






Как присвоить событие в run-time?


Как присвоить событие в run-time?



Пример стандартного присвоения события в run-time:



type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
  private
    procedure Click(Sender: TObject);
  end;

var  Form1: TForm1;

implementation

procedure TForm1.Click(Sender: TObject);
begin
  // do something
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  button1.OnClick:=Click;
end;

end.

Автор ответа: Vit
Взято с Vingrad.ru



А как сделать чтобы "procedure Click" была не методом класса, а отдельно стоящей функцией?


procedure Click(Self: TObject; Sender: TObject);
begin
  ...
end;

var
  evhandler: TNotifyEvent;
  TMethod(evhandler).Code := @Click;
  TMethod(evhandler).Data := nil;
  Button1.OnClick := evhandler;

  Без извращений можно так:

  TDummy = class
    class procedure Click(Sender: TObject);
  end;

  Button1.OnClick := TDummy.Click;

Автор ответа: Le Taon
Взято с Vingrad.ru



По идее, при вызове OnClick первым параметром будет запихнут указатель на экземпляр того класса который в этом OnClick хранится . Я в низкоуровневой реализации не силен, но кажись, так как параметры в процедурах в Delphi передаются через регистры, то ничего страшного не произойдет.


procedure C(Self:pointer;Sender:TObject);
begin
  TButton(Sender).Caption:='ee';
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  @Button1.OnClick:=@c;
end;

Self тут у нас будет равен nil, а Sender как раз и получается Sender'ом.

Автор ответа: Fantasist
Взято с Vingrad.ru




Как присвоить все значения полей одного класса, другому такому же классу?


Как присвоить все значения полей одного класса, другому такому же классу?





How can I assign all property values (or if it's not possible only published property values, or some of them) of one class (TComponent) to another instance of the same class? What I want to do is:

MyComponent1.{property1}:= MyComponent2.{property1};
{...}
MyComponent2.{propertyN} := MyComponent2.{propertyN};

Is there a better and shorter way to do this? I tried this: MyComponent1 := MyComponent2; But it doesn't work. Why not? Can I point to the second component ?


Answer 1:

MyComponent2 and MyComponent1 are pointers to your components, and this kind of assigment leads to MyComponent1 pointing to MyComponent2. But it will not copy its property values.

A better way is to override the assign method of your control, do all property assignment there and call it when you need to copy component attributes. Here's example:



procedure TMyComponent.Assign(Source: TPersistent);
begin
  if Source is TMyComponent then
  begin
    property1 := TMyComponent(Source).property1;
    { ... }
  end
  else
    inherited Assign(Source);
end;


To assign properties you'll need to set this line in the code:

MyComponent1.Assign(MyComponent2);

Tip by Serge Gubenko


procedure EqualClassProperties(AClass1, AClass2: TObject);
var
  PropList: PPropList;
  ClassTypeInfo: PTypeInfo;
  ClassTypeData: PTypeData;
  i: integer;
  NumProps: Integer;
  APersistent : TPersistent;
begin
  if AClass1.ClassInfo <> AClass2.ClassInfo then
    exit;
  ClassTypeInfo := AClass1.ClassInfo;
  ClassTypeData := GetTypeData(ClassTypeInfo);
  if ClassTypeData.PropCount <> 0 then
  begin
    GetMem(PropList, SizeOf(PPropInfo) * ClassTypeData.PropCount);
    try
      GetPropInfos(AClass1.ClassInfo, PropList);
      for i := 0 to ClassTypeData.PropCount - 1 do
        if not (PropList[i]^.PropType^.Kind = tkMethod) then
          {if Class1,2 is TControl/TWinControl on same form, its names must be unique}
          if PropList[i]^.Name <> 'Name' then
            if (PropList[i]^.PropType^.Kind = tkClass) then
            begin
              APersistent := TPersistent(GetObjectProp(AClass1, PropList[i]^.Name, TPersistent));
            if APersistent <> nil then
              APersistent.Assign(TPersistent(GetObjectProp(AClass2, PropList[i]^.Name, TPersistent)))
            end
            else
              SetPropValue(AClass1, PropList[i]^.Name, GetPropValue(AClass2, PropList[i]^.Name));
    finally
      FreeMem(PropList, SizeOf(PPropInfo) * ClassTypeData.PropCount);
    end;
  end;
end;


Note that this code skips object properties inherited other than TPersistent.

Tip by Gokhan Ersumer

Взято из






Как присвоить значение свойству selected в ListBox?


Как присвоить значение свойству selected в ListBox?



Свойство "selected" компонента ТListBox может быть использованно только если свойство MultiSelect установленно в True. Если Вы работаете с ListBox'ом у которого MultiSelect=false то используйте свойство ItemIndex.

procedure TForm1.Button1Click(Sender: TObject);
begin
   ListBox1.Items.Add('1');
   ListBox1.Items.Add('2');
   {This will fail on a single selection ListBox}
//   ListBox1.Selected[1] := true;
   ListBox1.ItemIndex := 1; {This is ok}
end;

Взято с Исходников.ru





Как прочитать адресную книгу Outlook (MSOffice) из Delphi и занести данные в таблицу *.db?


Как прочитать адресную книгу Outlook (MSOffice) из Delphi и занести данные в таблицу *.db?



Сперва сделай 'Import type Library' для Outlk80.olb, (расположен в \Program Files\Microsoft Office\Office).
После того, как появится файл 'Outlook_TLB.pas', можно нацарапать следующее:

uses ComObj, Outlook_TLB;procedure TForm1.Button1Click(Sender: TObject);var  MSOutlook,  MyNameSpace, 
 MyFolder,  MyItem: Variant;  s: string;  i: Integer;begin  try    MSOutlook := CreateOleObject('Outlook.Application');  
   MyNameSpace := MSOutlook.GetNameSpace('MAPI');    MyFolder := MyNamespace.GetDefaultFolder(olFolderContacts);  
     for i := 1 to MyFolder.Items.Count do 
begin
      s := s + #13#13'Contact No: ' + IntToStr(i) + #13#13; 
     MyItem := MyFolder.Items[i];
      s := s + 'BillingInformation: ' + MyItem.BillingInformation + #13;
      s := s + 'Body: ' + MyItem.Body + #13;      s := s + 'Categories: ' + MyItem.Categories + #13;  
    s := s + 'Companies: ' + MyItem.Companies + #13;      s := s + 'CreationTime: ' + DateTimeToStr(MyItem.CreationTime) + #13;
      s := s + 'EntryID: ' + MyItem.EntryID + #13;      s := s + 'Importance: ' + IntToStr(MyItem.Importance) + #13;
      s := s + 'LastModificationTime: ' + DateTimeToStr(MyItem.LastModificationTime) + #13;
      s := s + 'MessageClass: ' + MyItem.MessageClass + #13;      s := s + 'Mileage: ' + MyItem.Mileage + #13;
      s := s + 'NoAging: ' + IntToStr(MyItem.NoAging) + #13;      s := s + 'OutlookVersion: ' + MyItem.OutlookVersion + #13; 
     s := s + 'Saved: ' + IntToStr(MyItem.Saved) + #13;      s := s + 'Sensitivity: ' + IntToStr(MyItem.Sensitivity) + #13;
      s := s + 'Size: ' + IntToStr(MyItem.Size) + #13;      s := s + 'Subject: ' + MyItem.Subject + #13; 
     s := s + 'UnRead: ' + IntToStr(MyItem.UnRead) + #13;      s := s + 'Account: ' + MyItem.Account + #13; 
     s := s + 'Anniversary: ' + DateTimeToStr(MyItem.Anniversary) + #13;   
   s := s + 'AssistantName: ' + MyItem.AssistantName + #13; 
     s := s + 'AssistantTelephoneNumber: ' + MyItem.AssistantTelephoneNumber + #13;
      s := s + 'Birthday: ' + DateTimeToStr(MyItem.Birthday) + #13; 
     s := s + 'Business2TelephoneNumber: ' + MyItem.Business2TelephoneNumber + #13;  
    s := s + 'BusinessAddress: ' + MyItem.BusinessAddress + #13; 
     s := s + 'BusinessAddressCity: ' + MyItem.BusinessAddressCity + #13;   
   s := s + 'BusinessAddressCountry: ' + MyItem.BusinessAddressCountry + #13;
      s := s + 'BusinessAddressPostalCode: ' + MyItem.BusinessAddressPostalCode + #13; 
     s := s + 'BusinessAddressPostOfficeBox: ' + MyItem.BusinessAddressPostOfficeBox + #13;
      s := s + 'BusinessAddressState: ' + MyItem.BusinessAddressState + #13;
      s := s + 'BusinessAddressStreet: ' + MyItem.BusinessAddressStreet + #13; 
     s := s + 'BusinessFaxNumber: ' + MyItem.BusinessFaxNumber + #13;
      s := s + 'BusinessHomePage: ' + MyItem.BusinessHomePage + #13; 
     s := s + 'BusinessTelephoneNumber: ' + MyItem.BusinessTelephoneNumber + #13; 
     s := s + 'CallbackTelephoneNumber: ' + MyItem.CallbackTelephoneNumber + #13; 
     s := s + 'CarTelephoneNumber: ' + MyItem.CarTelephoneNumber + #13;
      s := s + 'Children: ' + MyItem.Children + #13;  
    s := s + 'CompanyAndFullName: ' + MyItem.CompanyAndFullName + #13;
      s := s + 'CompanyMainTelephoneNumber: ' + MyItem.CompanyMainTelephoneNumber + #13; 
     s := s + 'CompanyName: ' + MyItem.CompanyName + #13; 
     s := s + 'ComputerNetworkName: ' + MyItem.ComputerNetworkName + #13; 
     s := s + 'CustomerID: ' + MyItem.CustomerID + #13;
      s := s + 'Department: ' + MyItem.Department + #13; 
    s := s + 'Email1Address: ' + MyItem.Email1Address + #13;
     s := s + 'Email1AddressType: ' + MyItem.Email1AddressType + #13;
      s := s + 'Email1DisplayName: ' + MyItem.Email1DisplayName + #13;
      s := s + 'Email1EntryID: ' + MyItem.Email1EntryID + #13; 
     s := s + 'Email2Address: ' + MyItem.Email2Address + #13;
      s := s + 'Email2AddressType: ' + MyItem.Email2AddressType + #13; 
     s := s + 'Email2DisplayName: ' + MyItem.Email2DisplayName + #13;
      s := s + 'Email2EntryID: ' + MyItem.Email2EntryID + #13;
     s := s + 'Email3Address: ' + MyItem.Email3Address + #13;  
    s := s + 'Email3AddressType: ' + MyItem.Email3AddressType + #13; 
     s := s + 'Email3DisplayName: ' + MyItem.Email3DisplayName + #13;
      s := s + 'Email3EntryID: ' + MyItem.Email3EntryID + #13;
      s := s + 'FileAs: ' + MyItem.FileAs + #13; 
    s := s + 'FirstName: ' + MyItem.FirstName + #13;  
    s := s + 'FTPSite: ' + MyItem.FTPSite + #13; 
     s := s + 'FullName: ' + MyItem.FullName + #13; 
    s := s + 'FullNameAndCompany: ' + MyItem.FullNameAndCompany + #13;
      s := s + 'Gender: ' + IntToStr(MyItem.Gender) + #13;
      s := s + 'GovernmentIDNumber: ' + MyItem.GovernmentIDNumber + #13;
           s := s + 'Hobby: ' + MyItem.Hobby + #13; 
     s := s + 'Home2TelephoneNumber: ' + MyItem.Home2TelephoneNumber + #13; 
     s := s + 'HomeAddress: ' + MyItem.HomeAddress + #13; 
     s := s + 'HomeAddressCity: ' + MyItem.HomeAddressCity + #13; 
     s := s + 'HomeAddressCountry: ' + MyItem.HomeAddressCountry + #13; 
     s := s + 'HomeAddressPostalCode: ' + MyItem.HomeAddressPostalCode + #13;
      s := s + 'HomeAddressPostOfficeBox: ' + MyItem.HomeAddressPostOfficeBox + #13; 
     s := s + 'HomeAddressState: ' + MyItem.HomeAddressState + #13;
      s := s + 'HomeAddressStreet: ' + MyItem.HomeAddressStreet + #13;  
    s := s + 'HomeFaxNumber: ' + MyItem.HomeFaxNumber + #13;  
    s := s + 'HomeTelephoneNumber: ' + MyItem.HomeTelephoneNumber + #13;
      s := s + 'Initials: ' + MyItem.Initials + #13;
     s := s + 'ISDNNumber: ' + MyItem.ISDNNumber + #13;  
    s := s + 'JobTitle: ' + MyItem.JobTitle + #13; 
     s := s + 'Journal: ' + IntToStr(MyItem.Journal) + #13; 
     s := s + 'Language: ' + MyItem.Language + #13; 
     s := s + 'LastName: ' + MyItem.LastName + #13;  
    s := s + 'LastNameAndFirstName: ' + MyItem.LastNameAndFirstName + #13; 
     s := s + 'MailingAddress: ' + MyItem.MailingAddress + #13;
     s := s + 'MailingAddressCity: ' + MyItem.MailingAddressCity + #13; 
     s := s + 'MailingAddressCountry: ' + MyItem.MailingAddressCountry + #13; 
     s := s + 'MailingAddressPostalCode: ' + MyItem.MailingAddressPostalCode + #13;
      s := s + 'MailingAddressPostOfficeBox: ' + MyItem.MailingAddressPostOfficeBox + #13;
      s := s + 'MailingAddressState: ' + MyItem.MailingAddressState + #13;
      s := s + 'MailingAddressStreet: ' + MyItem.MailingAddressStreet + #13;  
    s := s + 'ManagerName: ' + MyItem.ManagerName + #13;
      s := s + 'MiddleName: ' + MyItem.MiddleName + #13; 
     s := s + 'MobileTelephoneNumber: ' + MyItem.MobileTelephoneNumber + #13; 
     s := s + 'NickName: ' + MyItem.NickName + #13; 
     s := s + 'OfficeLocation: ' + MyItem.OfficeLocation + #13;
      s := s + 'OrganizationalIDNumber: ' + MyItem.OrganizationalIDNumber + #13; 
     s := s + 'OtherAddress: ' + MyItem.OtherAddress + #13; 
     s := s + 'OtherAddressCity: ' + MyItem.OtherAddressCity + #13;  
    s := s + 'OtherAddressCountry: ' + MyItem.OtherAddressCountry + #13;
      s := s + 'OtherAddressPostalCode: ' + MyItem.OtherAddressPostalCode + #13;
      s := s + 'OtherAddressPostOfficeBox: ' + MyItem.OtherAddressPostOfficeBox + #13; 
     s := s + 'OtherAddressState: ' + MyItem.OtherAddressState + #13;
      s := s + 'OtherAddressStreet: ' + MyItem.OtherAddressStreet + #13; 
     s := s + 'OtherFaxNumber: ' + MyItem.OtherFaxNumber + #13; 
     s := s + 'OtherTelephoneNumber: ' + MyItem.OtherTelephoneNumber + #13;
      s := s + 'PagerNumber: ' + MyItem.PagerNumber + #13;
      s := s + 'PersonalHomePage: ' + MyItem.PersonalHomePage + #13; 
     s := s + 'PrimaryTelephoneNumber: ' + MyItem.PrimaryTelephoneNumber + #13;
      s := s + 'Profession: ' + MyItem.Profession + #13;
      s := s + 'RadioTelephoneNumber: ' + MyItem.RadioTelephoneNumber + #13;
      s := s + 'ReferredBy: ' + MyItem.ReferredBy + #13;
      s := s + 'SelectedMailingAddress: ' + In      s := s + 'Spouse: ' + MyItem.Spouse + #13;      s := s + 'Suffix: ' + MyItem.Suffix + #13; 
     s := s + 'TelexNumber: ' + MyItem.TelexNumber + #13;      s := s + 'Title: ' + MyItem.Title + #13; 
     s := s + 'TTYTDDTelephoneNumber: ' + MyItem.TTYTDDTelephoneNumber + #13; 
     s := s + 'User1: ' + MyItem.User1 + #13;      s := s + 'User2: ' + MyItem.User2 + #13; 
     s := s + 'User3: ' + MyItem.User3 + #13;      s := s + 'User4: ' + MyItem.User4 + #13; 
     s := s + 'UserCertificate: ' + MyItem.UserCertificate + #13;
      s := s + 'WebPage: ' + MyItem.WebPage + #13;
  end; 
   Memo1.Lines.Text := s;  except    on 
E: Exception do MessageDlg(E.Message + #13 + s, mtError, [mbOk], 0)
  end;  MSOutlook.Quit;
end;

Взято с сайта



Как прочитать байт из параллельного порта?


Как прочитать байт из параллельного порта?



Первый способ:


Var 
     BytesRead : BYTE; 
begin 
               asm                \{ Читаем порт (LPT1) через встроенный ассемблер  \} 
                 MOV dx,$379; 
                 IN  al,dx; 
                 MOV BytesRead,al; 
               end; 
BytesRead:=(BytesRead OR $07);   \{ OR а затем XOR данных \} 
BytesRead:=(BytesRead XOR $80);  \{ маскируем неиспользуемые биты  \} 


Второй способ :
Используем команды Turbo Pascal ...

  value:=port[$379]; \{ Прочитать из порта \} 
  port[$379]:=value; \{ Записать в порт \}

Взято с Исходников.ru



Как прочитать из модема?


Как прочитать из модема?



После предварительной настройки переменных, COM порт открывается как обычный файл. Так же пример показывает, как очищать буфер COM порта и читать из него.

Var 
PortSpec : array[0..255] of char;   
PortNo   : Word;   
success : Boolean;   
error:integer;   
begin 
FillChar(PortSpec,Sizeof(PortSpec),#0); 
StrPCopy(PortSpec,'Com1:19200,n,8,1'); 
PortSpec[3]:=Char(Ord(PortSpec[3])+Ord(PortNo)); 

if not BuildCommDCB(PortSpec,Mode) Then 
  Begin 
//какая-то ошибка... 
  Exit; 
  End; 

PortSpec[5]:=#0;    { 'Com1:' } 

Mode.Flags:=EV_RXCHAR +   EV_EVENT2;  { $1001 } 

  Com := CreateFile(PortSpec,GENERIC_READ or GENERIC_WRITE, 
                    0,    //* comm устройство открывается с эксклюзивным доступом*/ 
                    Nil, //* нет security битов */ 
                    OPEN_EXISTING, //* comm устройства должны использовать OPEN_EXISTING*/ 
                    0,    //* not overlapped I/O */ 
                    0  //* hTemplate должен быть NULL для comm устройств */ 
                     ); 
  if Com = INVALID_HANDLE_VALUE then Error := GetLastError; 
  Success := GetCommState(Com,Mode); 

  if not Success then  // Обработчик ошибки. 
  begin 

  end; 

  Mode.BaudRate := 19200; 
  Mode.ByteSize := 8; 
  Mode.Parity := NOPARITY; 
  Mode.StopBits := ONESTOPBIT;//нужен был для перезаписи в NT 

  Success := SetCommState(Com, Mode); 

  if not Success then  // Обработчик ошибки. 
  begin 

  end; 
end; 

Переменная "com" типа dword.

Вы так же можете очистить буффер COM порта
PurgeComm(Com,PURGE_RXCLEAR or PURGE_TXCLEAR);
И прочитать из него

Function ReadCh(Var Ch:Byte):dword; 
var 
n : dword; 
Begin 
  Readfile(Com,ch,1,result,nil); 
End;

Взято с Исходников.ru





Как прочитать/изменить startpage IE?


Как прочитать/изменить startpage IE?





uses 
  {...,}Registry; 
   
function GetIEStartPage: string; 
var 
  Reg: TRegistry; 
begin 
  Reg := TRegistry.Create; 
  try 
    Reg.RootKey := HKEY_CURRENT_USER; 
    Reg.OpenKey('Software\Microsoft\Internet Explorer\Main', False); 
    try 
      Result := Reg.ReadString('Start Page'); 
    except 
      Result := ''; 
    end; 
    Reg.CloseKey; 
  finally 
    Reg.Free; 
  end; 
end; 

function SetIEStartPage(APage: string): Boolean; 
var 
  Reg: TRegistry; 
begin 
  Reg := TRegistry.Create; 
  try 
    Reg.RootKey := HKEY_CURRENT_USER; 
    Reg.OpenKey('Software\Microsoft\Internet Explorer\Main', False); 
    try 
      Reg.WriteString('Start Page', APage); 
      Result := True; 
    finally 
      Reg.CloseKey; 
      Result := False; 
    end; 
  finally 
    Reg.Free; 
  end; 
end; 

// Show the Startpage 
procedure TForm1.Button1Click(Sender: TObject); 
begin 
  ShowMessage(GetIEStartPage); 
end; 

// Set the Startpage 
procedure TForm1.Button2Click(Sender: TObject); 
begin 
  SetIEStartPage('http://forum.vingrad.ru'); 
end; 


Взято с сайта



Как прочитать/изменить свойства Word документа?


Как прочитать/изменить свойства Word документа?





{ 1. Change MS Word properties via OLE } 

uses 
  ComObj; 

procedure TForm1.Button1Click(Sender: TObject); 
const 
  wdPropertyTitle = $00000001; 
  wdPropertySubject = $00000002; 
  wdPropertyAuthor = $00000003; 
  wdPropertyKeywords = $00000004; 
  wdPropertyComments = $00000005; 
  wdPropertyTemplate = $00000006; 
  wdPropertyLastAuthor = $00000007; 
  wdPropertyRevision = $00000008; 
  wdPropertyAppName = $00000009; 
  wdPropertyTimeLastPrinted = $0000000A; 
  wdPropertyTimeCreated = $0000000B; 
  wdPropertyTimeLastSaved = $0000000C; 
  wdPropertyVBATotalEdit = $0000000D; 
  wdPropertyPages = $0000000E; 
  wdPropertyWords = $0000000F; 
  wdPropertyCharacters = $00000010; 
  wdPropertySecurity = $00000011; 
  wdPropertyCategory = $00000012; 
  wdPropertyFormat = $00000013; 
  wdPropertyManager = $00000014; 
  wdPropertyCompany = $00000015; 
  wdPropertyBytes = $00000016; 
  wdPropertyLines = $00000017; 
  wdPropertyParas = $00000018; 
  wdPropertySlides = $00000019; 
  wdPropertyNotes = $0000001A; 
  wdPropertyHiddenSlides = $0000001B; 
  wdPropertyMMClips = $0000001C; 
  wdPropertyHyperlinkBase = $0000001D; 
  wdPropertyCharsWSpaces = $0000001E; 
const 
  AWordDoc = 'C:\Test.doc'; 
  wdSaveChanges = $FFFFFFFF; 
var 
  WordApp: OLEVariant; 
  SaveChanges: OleVariant; 
begin 
  try 
    WordApp := CreateOleObject('Word.Application'); 
  except 
    // Error.... 
    Exit; 
  end; 
  try 
    WordApp.Visible := False; 
    WordApp.Documents.Open(AWordDoc); 
    WordApp.ActiveDocument.BuiltInDocumentProperties[wdPropertyTitle].Value := 'Your Title...'; 
    WordApp.ActiveDocument.BuiltInDocumentProperties[wdPropertySubject].Value := 'Your Subject...'; 
    // ... 
    // ... 
  finally 
    SaveChanges := wdSaveChanges; 
    WordApp.Quit(SaveChanges, EmptyParam, EmptyParam); 
  end; 
end; 


{**********************************************} 



  2. Read MS Word properties via Structured Storage. 
  by Serhiy Perevoznyk 

uses 
  ComObj, ActiveX; 

const 
  FmtID_SummaryInformation: TGUID = 
    '{F29F85E0-4FF9-1068-AB91-08002B27B3D9}'; 

function FileTimeToDateTimeStr(F: TFileTime): string; 
var 
  LocalFileTime: TFileTime; 
  SystemTime: TSystemTime; 
  DateTime: TDateTime; 
begin 
  if Comp(F) = 0 then Result := '-' 
  else  
  begin 
    FileTimeToLocalFileTime(F, LocalFileTime); 
    FileTimeToSystemTime(LocalFileTime, SystemTime); 
    with SystemTime do 
      DateTime := EncodeDate(wYear, wMonth, wDay) + 
        EncodeTime(wHour, wMinute, wSecond, wMilliseconds); 
    Result := DateTimeToStr(DateTime); 
  end; 
end; 

function GetDocInfo(const FileName: WideString): string; 
var 
  I: Integer; 
  PropSetStg: IPropertySetStorage; 
  PropSpec: array[2..19] of TPropSpec; 
  PropStg: IPropertyStorage; 
  PropVariant: array[2..19] of TPropVariant; 
  Rslt: HResult; 
  S: string; 
  Stg: IStorage; 
begin 
  Result := ''; 
  try 
    OleCheck(StgOpenStorage(PWideChar(FileName), nil, STGM_READ or 
      STGM_SHARE_DENY_WRITE, 
      nil, 0, Stg)); 
    PropSetStg := Stg as IPropertySetStorage; 
    OleCheck(PropSetStg.Open(FmtID_SummaryInformation, 
      STGM_READ or STGM_SHARE_EXCLUSIVE, PropStg)); 
    for I := 2 to 19 do 
    begin 
      PropSpec[I].ulKind := PRSPEC_PROPID; 
      PropSpec[I].PropID := I; 
    end; 
    Rslt := PropStg.ReadMultiple(18, @PropSpec, @PropVariant); 
    OleCheck(Rslt); 
    if Rslt <> S_FALSE then for I := 2 to 19 do 
      begin 
        S := ''; 
        if PropVariant[I].vt = VT_LPSTR then 
          if Assigned(PropVariant[I].pszVal) then 
            S := PropVariant[I].pszVal; 
        case I of 
          2:  S  := Format('Title: %s', [S]); 
          3:  S  := Format('Subject: %s', [S]); 
          4:  S  := Format('Author: %s', [S]); 
          5:  S  := Format('Keywords: %s', [S]); 
          6:  S  := Format('Comments: %s', [S]); 
          7:  S  := Format('Template: %s', [S]); 
          8:  S  := Format('Last saved by: %s', [S]); 
          9:  S  := Format('Revision number: %s', [S]); 
          10: S := Format('Total editing time: %g sec', 
              [Comp(PropVariant[I].filetime) / 1.0E9]); 
          11: S := Format('Last printed: %s', 
              [FileTimeToDateTimeStr(PropVariant[I].filetime)]); 
          12: S := Format('Create time/date: %s', 
              [FileTimeToDateTimeStr(PropVariant[I].filetime)]); 
          13: S := Format('Last saved time/date: %s', 
              [FileTimeToDateTimeStr(PropVariant[I].filetime)]); 
          14: S := Format('Number of pages: %d', [PropVariant[I].lVal]); 
          15: S := Format('Number of words: %d', [PropVariant[I].lVal]); 
          16: S := Format('Number of characters: %d', 
              [PropVariant[I].lVal]); 
          17:; // thumbnail 
          18: S := Format('Name of creating application: %s', [S]); 
          19: S := Format('Security: %.8x', [PropVariant[I].lVal]); 
        end; 
        if S <> '' then Result := Result + S + #13; 
      end; 
  finally 
  end; 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
begin 
  if Opendialog1.Execute then 
    ShowMessage(GetDocInfo(opendialog1.FileName)); 
end; 


Взято с сайта




Как прочитать MP3 ID3-Tag?


Как прочитать MP3 ID3-Tag?






  Byte 1-3 = ID 'TAG' 
  Byte 4-33 = Titel / Title 
  Byte 34-63 = Artist 
  Byte 64-93 = Album 
  Byte 94-97 = Jahr / Year 
  Byte 98-127 = Kommentar / Comment 
  Byte 128 = Genre 



type 
  TID3Tag = record 
    ID: string[3]; 
    Titel: string[30]; 
    Artist: string[30]; 
    Album: string[30]; 
    Year: string[4]; 
    Comment: string[30]; 
    Genre: Byte; 
  end; 

const 
 Genres : array[0..146] of string = 
    ('Blues','Classic Rock','Country','Dance','Disco','Funk','Grunge', 
    'Hip- Hop','Jazz','Metal','New Age','Oldies','Other','Pop','R&B', 
    'Rap','Reggae','Rock','Techno','Industrial','Alternative','Ska', 
    'Death Metal','Pranks','Soundtrack','Euro-Techno','Ambient', 
    'Trip-Hop','Vocal','Jazz+Funk','Fusion','Trance','Classical', 
    'Instrumental','Acid','House','Game','Sound Clip','Gospel','Noise', 
    'Alternative Rock','Bass','Punk','Space','Meditative','Instrumental Pop', 
    'Instrumental Rock','Ethnic','Gothic','Darkwave','Techno-Industrial','Electronic', 
    'Pop-Folk','Eurodance','Dream','Southern Rock','Comedy','Cult','Gangsta', 
    'Top 40','Christian Rap','Pop/Funk','Jungle','Native US','Cabaret','New Wave', 
    'Psychadelic','Rave','Showtunes','Trailer','Lo-Fi','Tribal','Acid Punk', 
    'Acid Jazz','Polka','Retro','Musical','Rock & Roll','Hard Rock','Folk', 
    'Folk-Rock','National Folk','Swing','Fast Fusion','Bebob','Latin','Revival', 
    'Celtic','Bluegrass','Avantgarde','Gothic Rock','Progressive Rock', 
    'Psychedelic Rock','Symphonic Rock','Slow Rock','Big Band','Chorus', 
    'Easy Listening','Acoustic','Humour','Speech','Chanson','Opera', 
    'Chamber Music','Sonata','Symphony','Booty Bass','Primus','Porn Groove', 
    'Satire','Slow Jam','Club','Tango','Samba','Folklore','Ballad', 
    'Power Ballad','Rhytmic Soul','Freestyle','Duet','Punk Rock','Drum Solo', 
    'Acapella','Euro-House','Dance Hall','Goa','Drum & Bass','Club-House', 
    'Hardcore','Terror','Indie','BritPop','Negerpunk','Polsk Punk','Beat', 
    'Christian Gangsta','Heavy Metal','Black Metal','Crossover','Contemporary C', 
    'Christian Rock','Merengue','Salsa','Thrash Metal','Anime','JPop','SynthPop'); 


var 
  Form1: TForm1; 

implementation 

{$R *.dfm} 

function readID3Tag(FileName: string): TID3Tag; 
var 
  FS: TFileStream; 
  Buffer: array [1..128] of Char; 
begin 
  FS := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); 
  try 
    FS.Seek(-128, soFromEnd); 
    FS.Read(Buffer, 128); 
    with Result do 
    begin 
      ID := Copy(Buffer, 1, 3); 
      Titel := Copy(Buffer, 4, 30); 
      Artist := Copy(Buffer, 34, 30); 
      Album := Copy(Buffer, 64, 30); 
      Year := Copy(Buffer, 94, 4); 
      Comment := Copy(Buffer, 98, 30); 
      Genre := Ord(Buffer[128]); 
    end; 
  finally 
    FS.Free; 
  end; 
end; 

procedure TfrmMain.Button1Click(Sender: TObject); 
begin 
  if OpenDialog1.Execute then 
  begin 
    with readID3Tag(OpenDialog1.FileName) do 
    begin 
      LlbID.Caption := 'ID: ' + ID; 
      LlbTitel.Caption := 'Titel: ' + Titel; 
      LlbArtist.Caption := 'Artist: ' + Artist; 
      LlbAlbum.Caption := 'Album: ' + Album; 
      LlbYear.Caption := 'Year: ' + Year; 
      LlbComment.Caption := 'Comment: ' + Comment; 
      if (Genre >= 0) and (Genre <=146) then 
       LlbGenre.Caption := 'Genre: ' + Genres[Genre] 
      else 
       LlbGenre.Caption := 'N/A'; 
    end; 
  end; 
end; 


Взято с сайта



Как прочитать название порта принтера?


Как прочитать название порта принтера?





{... }

uses
  printers, winspool;

function GetCurrentPrinterHandle: THandle;
const
  Defaults: TPrinterDefaults = (pDatatype: nil; pDevMode: nil; DesiredAccess:
    PRINTER_ACCESS_USE or PRINTER_ACCESS_ADMINISTER);
var
  Device, Driver, Port: array[0..255] of char;
  hDeviceMode: THandle;
begin
  Printer.GetPrinter(Device, Driver, Port, hDeviceMode);
  if not OpenPrinter(@Device, Result, @Defaults) then
    RaiseLastWin32Error;
end;

procedure TForm1.Button1Click(Sender: TObject);

  procedure Display(const prefix: string; S: PChar);
  begin
    memo1.lines.add(prefix + string(S));
  end;

var
  pInfo: PPrinterInfo2;
  bytesNeeded: DWORD;
  hPrinter: THandle;
  i: Integer;
begin
  for i := 0 to printer.Printers.Count - 1 do
  begin
    Printer.PrinterIndex := i;
    hPrinter := GetCurrentPrinterHandle;
    try
      GetPrinter(hPrinter, 2, nil, 0, @bytesNeeded);
      pInfo := AllocMem(bytesNeeded);
      try
        GetPrinter(hPrinter, 2, pInfo, bytesNeeded, @bytesNeeded);
        Display('ServerName: ', pInfo^.pServerName);
        Display('PrinterName: ', pInfo^.pPrinterName);
        Display('ShareName: ', pInfo^.pShareName);
        Display('PortName: ', pInfo^.pPortName);
      finally
        FreeMem(pInfo);
      end;
    finally
      ClosePrinter(hPrinter);
    end;
  end;
end;

Взято с

Delphi Knowledge Base






Как прочитать очередь печати?


Как прочитать очередь печати?




uses 
  Winspool, Printers; 

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; 

function SavePChar(p: PChar): PChar; 
const 
  error: PChar = 'Nil'; 
begin 
  if not Assigned(p) then 
    Result := error 
  else 
    Result := p; 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
type 
  TJobs  = array [0..1000] of JOB_INFO_1; 
  PJobs = ^TJobs; 
var 
  hPrinter: THandle; 
  bytesNeeded, numJobs, i: Cardinal; 
  pJ: PJobs; 
begin 
  hPrinter := GetCurrentPrinterHandle; 
  try 
    EnumJobs(hPrinter, 0, 1000, 1, nil, 0, bytesNeeded, 
      numJobs); 
    pJ := AllocMem(bytesNeeded); 
    if not EnumJobs(hPrinter, 0, 1000, 1, pJ, bytesNeeded, 
      bytesNeeded, numJobs) then 
      RaiseLastWin32Error; 

    memo1.Clear; 
    if numJobs = 0 then 
      memo1.Lines.Add('No jobs in queue') 
    else 
      for i := 0 to Pred(numJobs) do 
        memo1.Lines.Add(Format('Printer %s, Job %s, Status (%d): %s', 
          [SavePChar(pJ^[i].pPrinterName), SavePChar(pJ^[i].pDocument), 
          pJ^[i].Status, SavePChar(pJ^[i].pStatus)])); 
  finally 
    ClosePrinter(hPrinter); 
  end; 
end; 

Взято с сайта




Как прочитать пароль, скрытый за звездочками?


Как прочитать пароль, скрытый за звездочками?



Наверно так: хотя классов может быть больше

procedure TForm1.Timer1Timer(Sender: TObject);
var
Wnd : HWND;  
lpClassName: array [0..$FF] of Char;  
begin
Wnd := WindowFromPoint(Mouse.CursorPos);  
GetClassName (Wnd, lpClassName, $FF);  
if ((strpas(lpClassName) = 'TEdit') or (strpas(lpClassName) = 'EDIT')) then  
PostMessage (Wnd, EM_SETPASSWORDCHAR, 0, 0);  
end; 

Автор ответа: Baa
Взято с Vingrad.ru


Здесь проблема: если страница памяти защищена, то её нельзя прочитать таким способом, но можно заменить PasswordChar(пример: поле ввода пароля в удаленном соединении)

Автор ответа: Mikel
Взято с Vingrad.ru





Как прочитать shortcut's link information?


Как прочитать shortcut's link information?




uses 
  ShlObj, 
  ComObj, 
  ActiveX, 
  CommCtrl; 

type 
  PShellLinkInfoStruct = ^TShellLinkInfoStruct; 
  TShellLinkInfoStruct = record 
    FullPathAndNameOfLinkFile: array[0..MAX_PATH] of Char; 
    FullPathAndNameOfFileToExecute: array[0..MAX_PATH] of Char; 
    ParamStringsOfFileToExecute: array[0..MAX_PATH] of Char; 
    FullPathAndNameOfWorkingDirectroy: array[0..MAX_PATH] of Char; 
    Description: array[0..MAX_PATH] of Char; 
    FullPathAndNameOfFileContiningIcon: array[0..MAX_PATH] of Char; 
    IconIndex: Integer; 
    HotKey: Word; 
    ShowCommand: Integer; 
    FindData: TWIN32FINDDATA; 
  end; 

procedure GetLinkInfo(lpShellLinkInfoStruct: PShellLinkInfoStruct); 
var 
  ShellLink: IShellLink; 
  PersistFile: IPersistFile; 
  AnObj: IUnknown; 
begin 
  // access to the two interfaces of the object 
  AnObj       := CreateComObject(CLSID_ShellLink); 
  ShellLink   := AnObj as IShellLink; 
  PersistFile := AnObj as IPersistFile; 

  // Opens the specified file and initializes an object from the file contents. 
  PersistFile.Load(PWChar(WideString(lpShellLinkInfoStruct^.FullPathAndNameOfLinkFile)), 0); 
  with ShellLink do 
  begin 
    // Retrieves the path and file name of a Shell link object. 
    GetPath(lpShellLinkInfoStruct^.FullPathAndNameOfFileToExecute, 
      SizeOf(lpShellLinkInfoStruct^.FullPathAndNameOfLinkFile), 
      lpShellLinkInfoStruct^.FindData, 
      SLGP_UNCPRIORITY); 

    // Retrieves the description string for a Shell link object. 
    GetDescription(lpShellLinkInfoStruct^.Description, 
      SizeOf(lpShellLinkInfoStruct^.Description)); 

    // Retrieves the command-line arguments associated with a Shell link object. 
    GetArguments(lpShellLinkInfoStruct^.ParamStringsOfFileToExecute, 
      SizeOf(lpShellLinkInfoStruct^.ParamStringsOfFileToExecute)); 

    // Retrieves the name of the working directory for a Shell link object. 
    GetWorkingDirectory(lpShellLinkInfoStruct^.FullPathAndNameOfWorkingDirectroy, 
      SizeOf(lpShellLinkInfoStruct^.FullPathAndNameOfWorkingDirectroy)); 

    // Retrieves the location (path and index) of the icon for a Shell link object. 
    GetIconLocation(lpShellLinkInfoStruct^.FullPathAndNameOfFileContiningIcon, 
      SizeOf(lpShellLinkInfoStruct^.FullPathAndNameOfFileContiningIcon), 
      lpShellLinkInfoStruct^.IconIndex); 

    // Retrieves the hot key for a Shell link object. 
    GetHotKey(lpShellLinkInfoStruct^.HotKey); 

    // Retrieves the show (SW_) command for a Shell link object. 
    GetShowCmd(lpShellLinkInfoStruct^.ShowCommand); 
  end; 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
const 
  br = #13#10; 
var 
  LinkInfo: TShellLinkInfoStruct; 
  s: string; 
begin 
  FillChar(LinkInfo, SizeOf(LinkInfo), #0); 
  LinkInfo.FullPathAndNameOfLinkFile := 'C:\WINNT\Profiles\user\Desktop\FileName.lnk'; 
  GetLinkInfo(@LinkInfo); 
  with LinkInfo do 
    s := FullPathAndNameOfLinkFile + br + 
      FullPathAndNameOfFileToExecute + br + 
      ParamStringsOfFileToExecute + br + 
      FullPathAndNameOfWorkingDirectroy + br + 
      Description + br + 
      FullPathAndNameOfFileContiningIcon + br + 
      IntToStr(IconIndex) + br + 
      IntToStr(LoByte(HotKey)) + br + 
      IntToStr(HiByte(HotKey)) + br + 
      IntToStr(ShowCommand) + br + 
      FindData.cFileName + br + 
      FindData.cAlternateFileName; 
  Memo1.Lines.Add(s); 
end; 

// Only for D3 or higher. 
// for D1,D2 users: http://www.hitekdev.com/delphi/shellutlexamples.html 



Взято с сайта



Как прочитать список возможностей принтера?


Как прочитать список возможностей принтера?




uses 
  Printers; 

//------------------------------------------------------------------------------ 
// Printer Device Debugging Code to TMemo Componenet 
// (c) - 1999 / by A. Weidauer 
// alex.weiauer@huckfinn.de 
//------------------------------------------------------------------------------ 

procedure GetDeviceSettings(DevCtrl: TMemo); 
var 
  Sep: string; 
  //----------------------------------------------- 
  procedure MakeInt(S: string; key: Integer); 
  begin 
    S := UpperCase(S); 
    DevCtrl.Lines.Add(UpperCase(Format(' %36S = %d ', 
      [s, GetDeviceCaps(Printer.Handle, Key)]))); 
  end; 
  //----------------------------------------------- 
  function StringToBits(S: string): string; 
  var 
    H: string; 
    i: Integer; 
    //----------------------------------------------- 
    function SubStr(C: Char): string; 
    begin 
      if c = '0' then SubStr := '0000'; 
      if c = '1' then SubStr := '0001'; 
      if c = '2' then SubStr := '0010'; 
      if c = '3' then SubStr := '0011'; 
      if c = '4' then SubStr := '0100'; 
      if c = '5' then SubStr := '0101'; 
      if c = '6' then SubStr := '0110'; 
      if c = '7' then SubStr := '0111'; 
      if c = '8' then SubStr := '1000'; 
      if c = '9' then SubStr := '1001'; 
      if c = 'A' then SubStr := '1010'; 
      if c = 'B' then SubStr := '1011'; 
      if c = 'C' then SubStr := '1100'; 
      if c = 'D' then SubStr := '1101'; 
      if c = 'E' then SubStr := '1110'; 
      if c = 'F' then SubStr := '1111'; 
    end; 
    //----------------------------------------------- 
  begin 
    StringToBits := ''; 
    S := UpperCase(s); 
    H := ''; 
    if Length(S) = 0 then Exit; 
    if Length(S) = 1 then S := '0000' + S; 
    if Length(S) = 2 then S := '000' + S; 
    if Length(S) = 3 then S := '00' + S; 
    if Length(S) = 4 then S := '0' + S; 
    for i := 1 to Length(s) do 
      H := H + ' ' + SubStr(S[i]); 
    StringToBits := H; 
  end; 
  //----------------------------------------------- 
  procedure MakeHex(S: string; key: Cardinal); 
  var 
    h: string; 
  begin 
    S := UpperCase(S); 
    h := Format('%X', [GetDeviceCaps(Printer.Handle, Key)]); 
    if Length(H) = 0 then Exit; 
    if Length(H) = 1 then H := '0000' + H; 
    if Length(H) = 2 then H := '000' + H; 
    if Length(H) = 3 then H := '00' + H; 
    if Length(H) = 4 then H := '0' + H; 
    DevCtrl.Lines.Add(''); 
    DevCtrl.Lines.Add(SEP); 
    DevCtrl.Lines.Add(''); 
    DevCtrl.Lines.Add(Format('%37S = Flags(%S) Key(%S)', 
      [s, h, StringToBits(H)] 
      )); 
    // (( GetDeviceCaps(Printer.Handle,Key), 
  end; 
  //---------------------------------------------------- 
  procedure MakeFlag(S: string; key, subKey: Cardinal); 
  var 
    i: Cardinal; 
  begin 
    S := UpperCase(S); 
    i := GetDeviceCaps(Printer.Handle, Key); 
    if i and SubKey <> 0 then 
      DevCtrl.Lines.Add(Format(' %34S = Flag(%4S) Key(%6D,%S)', 
        [s, 'ON ', SubKey, StringToBits(Format('%x', [SubKey]))])) 
    else 
      DevCtrl.Lines.Add(Format(' %34S = Flag(%4S) Key(%6D,%S)', 
        [s, 'OFF', SubKey, StringToBits(Format('%x', [SubKey]))])) 
  end; 
  //---------------------------------------------------- 
  function TechnoToStr(i: Integer): string; 
  begin 
    TechnoToStr := '#ERROR# is Unknwon'; 
    case i of 
      DT_PLOTTER: TechnoToStr    := 'Vector Plotter'; 
      DT_RASDISPLAY: TechnoToStr := 'Raster Display'; 
      DT_RASPRINTER: TechnoToStr := 'Raster Printer'; 
      DT_RASCAMERA: TechnoToStr  := 'Raster Camera'; 
      DT_CHARSTREAM: TechnoToStr := 'Character Stream'; 
      DT_METAFILE: TechnoToStr   := 'Metafile'; 
      DT_DISPFILE: TechnoToStr   := 'Display file'; 
    end; 
  end; 

  //--Main Procedure 
  //---------------------------------------------------------- 
begin 
  DevCtrl.SetFocus; 
  DevCtrl.Visible := False; 
  if Printer.PrinterIndex < 0 then Exit; 
  // Device Organisation 
  try 

    if not (GetMapMode(Printer.Handle) = MM_TEXT) then 
      SetMapMode(Printer.Handle, MM_Text); 
    DevCtrl.Clear; 

    Sep := '______________________________________________________________________________________________'; 
    DevCtrl.Lines.Add(sep); 
    DevCtrl.Lines.Add(''); 
    DevCtrl.Lines.Add(' PRINTER : ' + Printer.Printers[Printer.PrinterIndex]); 
    DevCtrl.Lines.Add(sep); 
    DevCtrl.Lines.Add(''); 

    DevCtrl.Lines.Add(sep); 
    DevCtrl.Lines.Add(''); 
    DevCtrl.Lines.Add(Format('%36S = %D', ['NUMBER Of COPIES', Printer.Copies])); 
    if Printer.Orientation = poLandscape then 
      DevCtrl.Lines.Add(Format('%36S = LANDSCAPE', ['ORIENTATION'])); 
    if Printer.Orientation = poPortrait then 
      DevCtrl.Lines.Add(Format('%36S = PORTRAIT', ['ORIENTATION'])); 


    DevCtrl.Lines.Add(sep); 
    DevCtrl.Lines.Add(''); 
    MakeInt('DRIVERVERSION', DRIVERVERSION); 
    DevCtrl.Lines.Add(Format(' %36S = %S', ['TECHNOLOGY', 
      UpperCase(TechnoToStr(GetDeviceCaps(Printer.Handle, Technology)))])); 
    DevCtrl.Lines.Add(sep); 
    DevCtrl.Lines.Add(''); 
    MakeInt('WIDTH [mm]', HORZSIZE); 
    MakeInt('HEIGHT [mm]', VERTSIZE); 
    MakeInt('WIDTH [pix]', HORZRES); 
    MakeInt('HEIGHT [pix]', VERTRES); 
    DevCtrl.Lines.Add(sep); 
    DevCtrl.Lines.Add(''); 
    MakeInt('Physical Width [pix]', PHYSICALWIDTH); 
    MakeInt('Physical Height[pix]', PHYSICALHEIGHT); 
    MakeInt('Physical Offset X [pix]', PHYSICALOFFSETX); 
    MakeInt('Physical Offset Y [pix]', PHYSICALOFFSETY); 
    MakeInt('SCALING FACTOR X', SCALINGFACTORX); 
    MakeInt('SCALING FACTOR Y', SCALINGFACTORY); 
    DevCtrl.Lines.Add(sep); 
    DevCtrl.Lines.Add(''); 
    MakeInt('horizontal [DPI]', LOGPIXELSX); 
    MakeInt('vertial [DPI]', LOGPIXELSY); 
    MakeInt('BITS PER PIXEL', BITSPIXEL); 
    MakeInt('COLOR PLANES', PLANES); 
    DevCtrl.Lines.Add(sep); 
    DevCtrl.Lines.Add(''); 
    MakeInt('NUMBER OF BRUSHES', NUMBRUSHES); 
    MakeInt('NUMBER OF PENS', NUMPENS); 
    MakeInt('NUMBER OF FONTS', NUMFONTS); 
    MakeInt('NUMBER OF COLORS', NUMCOLORS); 
    DevCtrl.Lines.Add(sep); 
    DevCtrl.Lines.Add(''); 
    MakeInt('ASPECT Ratio X [DPI]', ASPECTX); 
    MakeInt('ASPECT Ratio Y [DPI]', ASPECTY); 
    MakeInt('ASPECT Ratio XY [DPI]', ASPECTXY); 
    DevCtrl.Lines.Add(sep); 
    DevCtrl.Lines.Add(''); 
    MakeInt('SIZE OF PALETTE', SIZEPALETTE); 
    MakeInt('RESERVED TO SYSTEM PALETTE **', NUMRESERVED); 
    MakeInt('ACTUAL RASTER RESOLUTION **', COLORRES); 
    DevCtrl.Lines.Add(''); 
    DevCtrl.Lines.Add(' **...only true if KEY RASTERCAPS(RC_PALETTE)= ON'); 
    MakeFlag('... KEY RASTERCAPS (RC_PALETTE)', RasterCaps, RC_PALETTE); 
    DevCtrl.Lines.Add(''); 

    MakeHex('Clipping Capablities ', ClipCaps); 
    DevCtrl.Lines.Add(sep); 
    DevCtrl.Lines.Add(''); 
    MakeFlag('No Support ', ClipCaps, CP_NONE); 
    MakeFlag('Support Rectangles', ClipCaps, CP_RECTANGLE); 
    MakeFlag('Support PolyRegion 32 Bit', ClipCaps, CP_REGION); 

    MakeHex('Raster Printing Flags ', RasterCaps); 
    DevCtrl.Lines.Add(sep); 
    DevCtrl.Lines.Add(''); 
    MakeFlag('Support Bitmap Transfer', RasterCaps, RC_BITBLT); 
    MakeFlag('Support Banding', RasterCaps, RC_BANDING); 
    MakeFlag('Support Scaling', RasterCaps, RC_SCALING); 
    MakeFlag('Support Bitmaps > 64 kByte', RasterCaps, RC_BITMAP64); 
    MakeFlag('Support features of Win 2.0', RasterCaps, RC_GDI20_OUTPUT); 
    MakeFlag('Support Set~/GetDIBITS()', RasterCaps, RC_DI_BITMAP); 
    MakeFlag('Support Palette Devices', RasterCaps, RC_PALETTE); 
    MakeFlag('Support SetDIBitsToDevice()', RasterCaps, RC_DIBTODEV); 
    MakeFlag('Support Floodfill', RasterCaps, RC_FLOODFILL); 
    MakeFlag('Support StretchBlt()', RasterCaps, RC_STRETCHBLT); 
    MakeFlag('Support StretchBID()', RasterCaps, RC_STRETCHDIB); 
    MakeFlag('Support DIBS', RasterCaps, RC_DEVBITS); 

    MakeHex('Curve Printion Flages', CurveCaps); 
    DevCtrl.Lines.Add(sep); 
    DevCtrl.Lines.Add(''); 
    MakeFlag('No Curve support', CurveCaps, CC_NONE); 
    MakeFlag('Support Circles', CurveCaps, CC_Circles); 
    MakeFlag('Support Pie', CurveCaps, CC_PIE); 
    MakeFlag('Support Arces', CurveCaps, CC_CHORD); 
    MakeFlag('Support Ellipses', CurveCaps, CC_ELLIPSEs); 
    MakeFlag('Support WIDE FRAMES', CurveCaps, CC_WIDE); 
    MakeFlag('Support STYLED FRAMES', CurveCaps, CC_STYLED); 
    MakeFlag('Support WIDE&STYLED FRAMES', CurveCaps, CC_WIDESTYLED); 
    MakeFlag('Support INTERIORS', CurveCaps, CC_INTERIORS); 
    MakeFlag('Support ROUNDRECT', CurveCaps, CC_ROUNDRECT); 

    MakeHex('Line & Polygon Printing Flags', LineCaps); 
    DevCtrl.Lines.Add(sep); 
    DevCtrl.Lines.Add(''); 
    MakeFlag('No Line Support', LineCaps, LC_NONE); 
    MakeFlag('Support Polylines', LineCaps, LC_PolyLine); 
    MakeFlag('Support Marker', LineCaps, LC_Marker); 
    MakeFlag('Support PolyMarker', LineCaps, LC_PolyMarker); 
    MakeFlag('Support Wide Lines', LineCaps, LC_WIDE); 
    MakeFlag('Support STYLED Lines', LineCaps, LC_STYLED); 
    MakeFlag('Support WIDE&STYLED Lines', LineCaps, LC_WIDESTYLED); 
    MakeFlag('Support Lines Interiors', LineCaps, LC_INTERIORS); 

    MakeHex('Polygon (Areal) Printing Flags', POLYGONALCAPS); 
    DevCtrl.Lines.Add(sep); 
    DevCtrl.Lines.Add(''); 
    MakeFlag('No Polygon Support', PolygonalCaps, PC_NONE); 
    MakeFlag('Filling Alternate Polygons', PolygonalCaps, PC_POLYGON); 
    MakeFlag('Drawing Rectangles', PolygonalCaps, PC_RECTANGLE); 
    MakeFlag('Filling Winding Polygons', PolygonalCaps, PC_WINDPOLYGON); 
    MakeFlag('Drawing Trapezoid (??Flag)', PolygonalCaps, PC_Trapezoid); 
    MakeFlag('Drawing a ScanLine', PolygonalCaps, PC_SCANLINE); 
    MakeFlag('Drawing Wide Border', PolygonalCaps, PC_WIDE); 
    MakeFlag('Drawing Styled Border', PolygonalCaps, PC_STYLED); 
    MakeFlag('Drawing WIDE&STYLED Border', PolygonalCaps, PC_WIDESTYLED); 
    MakeFlag('Drawing Interiors', PolygonalCaps, PC_INTERIORS); 

    MakeHex('Text Printing Flags', TEXTCAPS); 
    DevCtrl.Lines.Add(sep); 
    DevCtrl.Lines.Add(''); 
    MakeFlag('Support Character Output Precision', TextCaps, TC_OP_CHARACTER); 
    MakeFlag('Support Stroke Output Precision', TextCaps, TC_OP_STROKE); 
    MakeFlag('Support Stroke Clip Precision', TextCaps, TC_CP_STROKE); 
    MakeFlag('Support 90° Character Rotation', TextCaps, TC_CR_90); 
    MakeFlag('Support any Character Rotaion', TextCaps, TC_CR_ANY); 
    MakeFlag('Support Character Scaling in X&Y', TextCaps, TC_SF_X_YINDEP); 
    MakeFlag('Support Character Scaling REAL', TextCaps, TC_SA_DOUBLE); 
    MakeFlag('Support Character Scaling RATIONAL', TextCaps, TC_SA_INTEGER); 
    MakeFlag('Support Character Scaling EXACT', TextCaps, TC_SA_CONTIN); 
    MakeFlag('Support Character Weight REAL', TextCaps, TC_EA_DOUBLE); 
    MakeFlag('Support Character Italic', TextCaps, TC_IA_ABLE); 
    MakeFlag('Support Character Underline', TextCaps, TC_UA_ABLE); 
    MakeFlag('Support Character Strikeout', TextCaps, TC_SO_ABLE); 
    MakeFlag('Support Character as RASTER FONT', TextCaps, TC_RA_ABLE); 
    MakeFlag('Support Character as VECTOR FONT', TextCaps, TC_VA_ABLE); 
    MakeFlag('Reserved Flag ???', TextCaps, TC_Reserved); 
    MakeFlag('DEVICE NOT USE a SCROLLBIT BLOCK ?', TextCaps, TC_SCROLLBLT); 
    DevCtrl.Lines.Insert(0, '..THE RESULTS ARE:'); 
  except 
    // MessageDlg('The Current Printer is not valid ! ', 
    // mtError,[mbok],0); 
    Printer.PrinterIndex := -1; 
    DevCtrl.Lines.Add(' ! The Printer is not valid !'); 
  end; 
  DevCtrl.Visible := True; 
  DevCtrl.SetFocus; 
end; 

Взято с сайта



Как прочитать свойства видеофайла?


Как прочитать свойства видеофайла?





Below is some code to get some of the data. To use the DirectDraw/ DirectShow calls you need either the older DSHOW.PAS (DX6) or more current DirectShow.pas header conversion from the Project JEDI web site:


type
TDSMediaInfo = record
    SurfaceDesc: TDDSurfaceDesc;
    Pitch: integer;
    PixelFormat: TPixelFormat;
    MediaLength: Int64;
    AvgTimePerFrame: Int64;
    FrameCount: integer;
    Width: integer;
    Height: integer;
    FileSize: Int64;
  end;

function GetHugeFileSize(const FileName: string): int64;
var
  FileHandle: hFile;
begin
  FileHandle := FileOpen(FileName, fmOpenRead or fmShareDenyNone);
  try
    LARGE_INTEGER(Result).LowPart := GetFileSize(FileHandle, @LARGE_INTEGER(Result).HighPart);
    if LARGE_INTEGER(Result).LowPart = $FFFFFFFF then
      Win32Check(GetLastError = NO_ERROR);
  finally
    FileClose(FileHandle);
  end;
end;

function GetMediaInfo(FileName: WideString): TDSMediaInfo;
var
  DirectDraw: IDirectDraw;
  AMStream: IAMMultiMediaStream;
  MMStream: IMultiMediaStream;
  PrimaryVidStream: IMediaStream;
  DDStream: IDirectDrawMediaStream;
  GraphBuilder: IGraphBuilder;
  MediaSeeking: IMediaSeeking;
  TimeStart, TimeStop: Int64;
  DesiredSurface: TDDSurfaceDesc;
  DDSurface: IDirectDrawSurface;
begin
  if FileName = '' then
    raise Exception.Create('No File Name Specified');
  OleCheck(DirectDrawCreate(nil, DirectDraw, nil));
  DirectDraw.SetCooperativeLevel(GetDesktopWindow(), DDSCL_NORMAL);
  Result.FileSize := GetHugeFileSize(FileName);
  AMStream := IAMMultiMediaStream(CreateComObject(CLSID_AMMultiMediaStream));
  OleCheck(AMStream.Initialize(STREAMTYPE_READ, AMMSF_NOGRAPHTHREAD, nil));
  OleCheck(AMStream.AddMediaStream(DirectDraw, MSPID_PrimaryVideo, 0, IMediaStream(nil^)));
  OleCheck(AMStream.OpenFile(PWideChar(FileName), AMMSF_NOCLOCK));
  AMStream.GetFilterGraph(GraphBuilder);
  MediaSeeking := GraphBuilder as IMediaSeeking;
  MediaSeeking.GetDuration(Result.MediaLength);
  MMStream := AMStream as IMultiMediaStream;
  OleCheck(MMStream.GetMediaStream(MSPID_PrimaryVideo, PrimaryVidStream));
  DDStream := PrimaryVidStream as IDirectDrawMediaStream;
  DDStream.GetTimePerFrame(Result.AvgTimePerFrame);
  {Result.FrameCount := Result.MediaLength div Result.AvgTimePerFrame;}
  { TODO : Test for better accuracy }
  Result.FrameCount := Round(Result.MediaLength / Result.AvgTimePerFrame);
  Result.MediaLength := Result.FrameCount * Result.AvgTimePerFrame;
  ZeroMemory(@DesiredSurface, SizeOf(DesiredSurface));
  DesiredSurface.dwSize := Sizeof(DesiredSurface);
  OleCheck(DDStream.GetFormat(TDDSurfaceDesc(nil^), IDirectDrawPalette(nil^),
    DesiredSurface, DWord(nil^)));
  Result.SurfaceDesc := DesiredSurface;
  DesiredSurface.ddsCaps.dwCaps := DesiredSurface.ddsCaps.dwCaps or
    DDSCAPS_OFFSCREENPLAIN or DDSCAPS_SYSTEMMEMORY;
  DesiredSurface.dwFlags := DesiredSurface.dwFlags or DDSD_CAPS or DDSD_PIXELFORMAT;
  {Create a surface here to get vital statistics}
  OleCheck(DirectDraw.CreateSurface(DesiredSurface, DDSurface, nil));
  OleCheck(DDSurface.GetSurfaceDesc(DesiredSurface));
  Result.Pitch := DesiredSurface.lPitch;
  if DesiredSurface.ddpfPixelFormat.dwRGBBitCount = 24 then
    Result.PixelFormat := pf24bit
  else if DesiredSurface.ddpfPixelFormat.dwRGBBitCount = 32 then
    Result.PixelFormat := pf32bit;
  Result.Width := DesiredSurface.dwWidth;
  Result.Height := DesiredSurface.dwHeight;
end;


Взято с

Delphi Knowledge Base






Как прочитать свойство напрямую из его ресурса?


Как прочитать свойство напрямую из его ресурса?





Does anyone know if there is an easy way to load the value of a component's property directly from its resource without creating the component? Something like:

ifReadPropertyValue('Form1.Button1', 'width') > 1000 then
  ShowMessage('You are about to create a big button!');

function TForm1.ReadProp(r: TReader): string;
begin
  result := '';
  {Determine the value type of the property, read it with the appropriate method of TReader
  and convert it to string. Not all value types are implemented here but you get the idea.}
  case r.NextValue of
    vaInt8, vaInt16, vaInt32:
      result := IntToStr(r.ReadInteger);
    vaExtended:
      result := FloatToStr(r.ReadFloat);
    vaString:
      result := r.ReadString;
    else
      r.SkipValue;  {Not implemented}
  end;
end;


procedure TForm1.ReadRes(PropPath: string; r: TReader);
var
  p: string;
begin
  {Skip the class name}
  r.ReadStr;
  {Construct the property path}
  if PropPath = '' then
    p := r.ReadStr
  else
    p := PropPath + '.' + r.ReadStr;
  {Read all properties and its values and fill them into the memo}
  while not r.EndOfList do
    Memo1.Lines.Add(p + '.' + r.ReadStr + ' = ' + ReadProp(r));
  {Skip over the end of the list of the properties of this component}
  r.CheckValue(vaNull);
  {Recursively read the properties of all sub-components}
  while not r.EndOfList do
  begin
    ReadRes(p, r);
    r.CheckValue(vaNull);
  end;
end;


procedure TForm1.Button1Click(Sender: TObject);
var
  strm: TResourceStream;
  Reader: TReader;
begin
  strm := TResourceStream.Create(HInstance, 'TForm1', RT_RCDATA);
  Reader := TReader.Create(strm, 1024);
  try
    Memo1.Clear;
    Reader.ReadSignature;
    ReadRes('', Reader);
  finally
    Reader.Free;
    strm.Free;
  end;
end;


Only one small problem.
r.SkipValue was protected (in D5) but I hacked that out with the following code:


type THackReader = class(TReader);
{ ... }
  THackReader(r).SkipValue;


And now it works like a charm.

Tip by Michael Duerig and Tjipke A. van der Plaats

Взято из






Как прочитать/установить принтер по умолчанию?


Как прочитать/установить принтер по умолчанию?




uses 
  Printers, Messages; 

function GetDefaultPrinter: string; 
var 
  ResStr: array[0..255] of Char; 
begin 
  GetProfileString('Windows', 'device', '', ResStr, 255); 
  Result := StrPas(ResStr); 
end; 

procedure SetDefaultPrinter1(NewDefPrinter: string); 
var 
  ResStr: array[0..255] of Char; 
begin 
  StrPCopy(ResStr, NewdefPrinter); 
  WriteProfileString('windows', 'device', ResStr); 
  StrCopy(ResStr, 'windows'); 
  SendMessage(HWND_BROADCAST, WM_WININICHANGE, 0, Longint(@ResStr)); 
end; 

procedure SetDefaultPrinter2(PrinterName: string); 
var 
  I: Integer; 
  Device: PChar; 
  Driver: PChar; 
  Port: PChar; 
  HdeviceMode: THandle; 
  aPrinter: TPrinter; 
begin 
  Printer.PrinterIndex := -1; 
  GetMem(Device, 255); 
  GetMem(Driver, 255); 
  GetMem(Port, 255); 
  aPrinter := TPrinter.Create; 
  try 
    for I := 0 to Printer.Printers.Count - 1 do 
    begin 
      if Printer.Printers = PrinterName then 
      begin 
        aprinter.PrinterIndex := i; 
        aPrinter.getprinter(device, driver, port, HdeviceMode); 
        StrCat(Device, ','); 
        StrCat(Device, Driver); 
        StrCat(Device, Port); 
        WriteProfileString('windows', 'device', Device); 
        StrCopy(Device, 'windows'); 
        SendMessage(HWND_BROADCAST, WM_WININICHANGE, 
          0, Longint(@Device)); 
      end; 
    end; 
  finally 
    aPrinter.Free; 
  end; 
  FreeMem(Device, 255); 
  FreeMem(Driver, 255); 
  FreeMem(Port, 255); 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
begin 
  label1.Caption := GetDefaultPrinter2; 
end; 

//Fill the combobox with all available printers 
procedure TForm1.FormCreate(Sender: TObject); 
begin 
  Combobox1.Items.Clear; 
  Combobox1.Items.AddStrings(Printer.Printers); 
end; 

//Set the selected printer in the combobox as default printer 
procedure TForm1.Button2Click(Sender: TObject); 
begin 
  SetDefaultPrinter(Combobox1.Text); 
end; 

Взято с сайта




Как прочитать весь список Published методов?


Как прочитать весь список Published методов?



procedureEnumMethods( aClass: TClass; lines: TStrings );
  
  type
    TMethodtableEntry = packed Record
      len: Word;
      adr: Pointer;
      name: ShortString;
  end;
  {Note: name occupies only the size required, so it is not a true shortstring! The actual
  entry size is variable, so the method table is not an array of TMethodTableEntry!}

var
  pp: ^Pointer;
  pMethodTable: Pointer;
  pMethodEntry: ^TMethodTableEntry;
  i, numEntries: Word;
begin
  if aClass = nil then
    Exit;
  pp := Pointer(Integer( aClass ) + vmtMethodtable);
  pMethodTable := pp^;
  lines.Add(format('Class %s: method table at %p', [aClass.Classname, pMethodTable ] ));
  if pMethodtable <> nil then
  begin
    {first word of the method table contains the number of entries}
    numEntries := PWord( pMethodTable )^;
    lines.Add(format('  %d published methods', [numEntries] ));
    {make pointer to first method entry, it starts at the second word of the table}
    pMethodEntry := Pointer(Integer( pMethodTable ) + 2);
    for i := 1 to numEntries do
    begin
      with pMethodEntry^ do
        lines.Add(format( '  %d: len: %d, adr: %p, name: %s', [i, len, adr, name] ));
      {make pointer to next method entry}
      pMethodEntry := Pointer(Integer( pMethodEntry ) + pMethodEntry^.len);
    end;
  end;
    EnumMethods( aClass.ClassParent, lines );
end;


procedure TForm2.Button1Click(Sender: TObject);
begin
  memo1.clear;
  EnumMethods( Classtype, memo1.lines );
end;

Взято из




function GetComponentProperties(Instance: TPersistent; AList: TStrings): Integer;
var
  I, Count: Integer;
  PropInfo: PPropInfo;
  PropList: PPropList;
begin
  Result := 0;
  Count := GetTypeData(Instance.ClassInfo)^.PropCount;
  if Count > 0 then
  begin
    GetMem(PropList, Count * SizeOf(Pointer));
    try
      GetPropInfos(Instance.ClassInfo, PropList);
      for I := 0 to Count - 1 do
      begin
        PropInfo := PropList^[I];
        if PropInfo = nil then
          Break;
        if IsStoredProp(Instance, PropInfo) then
        begin
          {
          case PropInfo^.PropType^.Kind of
            tkInteger:
            tkMethod:
            tkClass:
            ...
          end;
          }
        end;
        Result := AList.Add(PropInfo^.Name);
      end;
    finally
      FreeMem(PropList, Count * SizeOf(Pointer));
    end;
  end;
end;

Tip by Grega Loboda

uses
  TypInfo

procedure ListProperties(AInstance: TPersistent; AList: TStrings);
var
  i: integer;
  pInfo: PTypeInfo;
  pType: PTypeData;
  propList: PPropList;
  propCnt: integer;
  tmpStr: string;
begin
  pInfo := AInstance.ClassInfo;
  if (pInfo = nil) or (pInfo^.Kind <> tkClass) then
    raise Exception.Create('Invalid type information');
  pType := GetTypeData(pInfo);  {Pointer to TTypeData}
  AList.Add('Class name: ' + pInfo^.Name);
  {If any properties, add them to the list}
  propCnt := pType^.PropCount;
  if propCnt > 0 then
  begin
    AList.Add(EmptyStr);
    tmpStr := IntToStr(propCnt) + ' Propert';
    if propCnt > 1 then
      tmpStr := tmpStr + 'ies'
    else
      tmpStr := tmpStr + 'y';
    AList.Add(tmpStr);
    FillChar(tmpStr[1], Length(tmpStr), '-');
    AList.Add(tmpStr);
    {Get memory for the property list}
    GetMem(propList, sizeOf(PPropInfo) * propCnt);
    try
      {Fill in the property list}
      GetPropInfos(pInfo, propList);
      {Fill in info for each property}
      for i := 0 to propCnt - 1 do
        AList.Add(propList[i].Name+': '+propList[i].PropType^.Name);
    finally
      FreeMem(propList, sizeOf(PPropInfo) * propCnt);
    end;
  end;
end;


function GetPropertyList(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;


And calling this code by:


ListProperties(TProject(treeview1.items[0].data), memo3.lines);


My tProject is defined as


type
   TProject = class(tComponent)
   private
     FNaam: string;
     procedure SetNaam(const Value: string);
   public
     constructor Create(AOwner: tComponent);
     destructor Destroy;
   published
     property Naam: string read FNaam write SetNaam;
   end;


Also note the output, there seem to be 2 standard properties (Name and Tag) !

Memo3
Class name: TProject

3 Properties
-------------------
Name: TComponentName
Tag: Integer
Naam: String



Tip by Ronan van Riet

Взято из








Как прочитать владельца файла?


Как прочитать владельца файла?





// When you create a file or directory, you become the owner of it. 
// With GetFileOwner you get the owner of a file. 

function GetFileOwner(FileName: string; 
  var Domain, Username: string): Boolean; 
var 
  SecDescr: PSecurityDescriptor; 
  SizeNeeded, SizeNeeded2: DWORD; 
  OwnerSID: PSID; 
  OwnerDefault: BOOL; 
  OwnerName, DomainName: PChar; 
  OwnerType: SID_NAME_USE; 
begin 
  GetFileOwner := False; 
  GetMem(SecDescr, 1024); 
  GetMem(OwnerSID, SizeOf(PSID)); 
  GetMem(OwnerName, 1024); 
  GetMem(DomainName, 1024); 
  try 
    if not GetFileSecurity(PChar(FileName), 
      OWNER_SECURITY_INFORMATION, 
      SecDescr, 1024, SizeNeeded) then 
      Exit; 
    if not GetSecurityDescriptorOwner(SecDescr, 
      OwnerSID, OwnerDefault) then 
      Exit; 
    SizeNeeded  := 1024; 
    SizeNeeded2 := 1024; 
    if not LookupAccountSID(nil, OwnerSID, OwnerName, 
      SizeNeeded, DomainName, SizeNeeded2, OwnerType) then 
      Exit; 
    Domain   := DomainName; 
    Username := OwnerName; 
  finally 
    FreeMem(SecDescr); 
    FreeMem(OwnerName); 
    FreeMem(DomainName); 
  end; 
  GetFileOwner := True; 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
var 
  Domain, Username: string; 
begin 
  GetFileOwner('YourFile.xyz', domain, username); 
  ShowMessage(username + '@' + domain); 
end; 

// Note: Only works unter NT.
Взято с сайта



Как прочитать время компиляции проги?


Как прочитать время компиляции проги?



Дату компилляции вытащить нельзя. Можно дату Build (т.е. дату когда ты сделал опрерацию Build All, или самую первую компилляцию)

1) Ставим библиотеку RxLib
2) Идем в опции проэкта, закладка Version Info, отмечаем птичкой - include version info
3) В коде пишем следующее


uses
  Rxverinf;

procedure TForm1.Button1Click(Sender: TObject);
begin
  with TVersionInfo.create(paramstr(0)) do
  try
    caption := datetimetostr(verfiledate);
  finally
    free;
  end;
end;

Автор ответа: Vit
Взято с Vingrad.ru




Как прочитать заголовок wav файла?


Как прочитать заголовок wav файла?





type
TWaveHeader = record
    ident1: array[0..3] of Char;      // Must be "RIFF"
    len: DWORD;                       // Remaining length after this header
    ident2: array[0..3] of Char;      // Must be "WAVE"
    ident3: array[0..3] of Char;      // Must be "fmt "
    reserv: DWORD;                    // Reserved 4 bytes
    wFormatTag: Word;                 // format type
    nChannels: Word;                  // number of channels (i.e. mono, stereo, etc.)
    nSamplesPerSec: DWORD;            //sample rate
    nAvgBytesPerSec: DWORD;           //for buffer estimation
    nBlockAlign: Word;                //block size of data
    wBitsPerSample: Word;             //number of bits per sample of mono data
    cbSize: Word;                     //the count in bytes of the size of
    ident4: array[0..3] of Char;      //Must be "data"
end;


With this structure you can get all the information's about a wave file you want to.
After this header following the wave data which contains the data for playing the wave file.

Now we trying to get the information's from a wave file. To be sure it's really a wave file, we test the information's:


function GetWaveHeader(FileName: TFilename): TWaveHeader;
const
  riff = 'RIFF';
  wave = 'WAVE';
var
  f: TFileStream;
  w: TWaveHeader;
begin
  if not FileExists(Filename) then
    exit; //exit the function if the file does not exists

  try
    f := TFileStream.create(Filename, fmOpenRead);
    f.Read(w, Sizeof(w)); //Reading the file header

    if w.ident1 <> riff then
    begin //Test if it is a RIFF file, otherwise exit
      Showmessage('This is not a RIFF File');
      exit;
    end;

    if w.ident2 <> wave then
    begin //Test if it is a wave file, otherwise exit
      Showmessage('This is not a valid wave file');
      exit;
    end;

  finally
    f.free;
  end;

  Result := w;
end;

Взято с

Delphi Knowledge Base






Как программе удалить саму себя?


Как программе удалить саму себя?



Первый способ:

uses 
  Windows, SysUtils; 

procedure DeleteMe; 
var 
  BatchFile: TextFile; 
  BatchFileName: string; 
  ProcessInfo: TProcessInformation; 
  StartUpInfo: TStartupInfo; 
begin 
  { создаём бат-файл в директории приложения }
  BatchFileName := ExtractFilePath(ParamStr(0)) + '$$336699.bat'; 

  { открываем и записываем в файл }
  AssignFile(BatchFile, BatchFileName); 
  Rewrite(BatchFile); 

  Writeln(BatchFile, ':try'); 
  Writeln(BatchFile, 'del "' + ParamStr(0) + '"'); 
  Writeln(BatchFile, 
    'if exist "' + ParamStr(0) + '"' + ' goto try'); 
  Writeln(BatchFile, 'del "' + BatchFileName + '"'); 
  CloseFile(BatchFile); 

  FillChar(StartUpInfo, SizeOf(StartUpInfo), $00); 
  StartUpInfo.dwFlags := STARTF_USESHOWWINDOW; 
  StartUpInfo.wShowWindow := SW_HIDE; 

  if CreateProcess(nil, PChar(BatchFileName), nil, nil, 
     False, IDLE_PRIORITY_CLASS, nil, nil, StartUpInfo, 
     ProcessInfo) then 
  begin 
    CloseHandle(ProcessInfo.hThread); 
    CloseHandle(ProcessInfo.hProcess); 
  end; 

end;



А вот тот же способ, но немного модифицированный:

program delete2; 

uses 
  SysUtils, 
  windows; 

var 
   BatchFile: TextFile; 
   BatchFileName : string; 
   TM : Cardinal; 
   TempMem : PChar; 

begin 
    BatchFileName:=ExtractFilePath(ParamStr(0))+ '$$336699.bat'; 


   AssignFile(BatchFile, BatchFileName); 
   Rewrite(BatchFile); 

   Writeln(BatchFile,':try'); 
   Writeln(BatchFile,'del "' + ParamStr(0) + '"'); 
   Writeln(BatchFile,'if exist "' + ParamStr(0) + '" goto try'); 
   Writeln(BatchFile,'del "' + BatchFileName + '"'); 
   CloseFile(BatchFile); 

   TM:=70; 
   GetMem (TempMem,TM); 
   GetShortPathName (pchar(BatchFileName), TempMem, TM); 
   BatchFileName:=TempMem; 
   FreeMem(TempMem); 

   winexec(Pchar(BatchFileName),sw_hide); 

   halt; 

end.




Второй способ:

procedure DeleteSelf; 
var 
  module: HModule; 
  buf: array[0..MAX_PATH - 1] of char; 
  p: ULong; 
  hKrnl32: HModule; 
  pExitProcess, 
  pDeleteFile, 
  pFreeLibrary: pointer; 
begin 
  module := GetModuleHandle(nil); 
  GetModuleFileName(module, buf, SizeOf(buf)); 
  CloseHandle(THandle(4)); 
  p := ULONG(module) + 1; 
  hKrnl32 := GetModuleHandle('kernel32'); 
  pExitProcess := GetProcAddress(hKrnl32, 'ExitProcess'); 
  pDeleteFile := GetProcAddress(hKrnl32, 'DeleteFileA'); 
  pFreeLibrary := GetProcAddress(hKrnl32, 'FreeLibrary'); 
  asm 
    lea eax, buf 
    push 0 
    push 0 
    push eax 
    push pExitProcess 
    push p 
    push pDeleteFile 
    push pFreeLibrary 
    ret 
  end; 
end;


Взято с Исходников.ru



Как программно добавить принтер?


Как программно добавить принтер?




Чтобы программно добавить принтер, необходимо воспользоваться API функцией AddPrinter, которая имеет три параметра:

·Имя принтера
·Уровень печати  
·Описание принтера  

Следующий пример является надстройкой для этой функции. Для этого необходимо знать Имя принтера, которое будет отображаться в Проводнике, имя порта, к которому подключён принтер (т.е. LPT1:), имя драйвера (прийдётся посмотреть вручную) и имя процессора печати (который обычно "winprint").


unit unit_AddPrinter;

interface

function AddAPrinter(PrinterName, PortName,
DriverName, PrintProcessor: string): boolean;

implementation

uses
  SysUtils,
  WinSpool,
  Windows;

function AddAPrinter(PrinterName, PortName,
DriverName, PrintProcessor: string):     boolean;
var 
  pName: PChar; 
  Level: DWORD; 
  pPrinter: PPrinterInfo2; 
begin 

  pName := nil; 
  Level := 2; 
  New(pPrinter); 
  pPrinter^.pServerName := nil; 
  pPrinter^.pShareName := nil; 
  pPrinter^.pComment := nil; 
  pPrinter^.pLocation := nil; 
  pPrinter^.pDevMode := nil;
  pPrinter^.pSepFile := nil; 
  pPrinter^.pDatatype := nil; 
  pPrinter^.pParameters := nil; 
  pPrinter^.pSecurityDescriptor := nil; 
  pPrinter^.Attributes := 0;
  pPrinter^.Priority := 0;
  pPrinter^.DefaultPriority := 0;
  pPrinter^.StartTime := 0;
  pPrinter^.UntilTime := 0;
  pPrinter^.Status := 0;
  pPrinter^.cJobs := 0;
  pPrinter^.AveragePPM :=0;

  pPrinter^.pPrinterName := PCHAR(PrinterName);
  pPrinter^.pPortName := PCHAR(PortName);
  pPrinter^.pDriverName := PCHAR(DriverName);
  pPrinter^.pPrintProcessor := PCHAR(PrintProcessor);

  if AddPrinter(pName, Level, pPrinter) <> 0 then
    Result := true
  else
  begin
    // ShowMessage(inttostr(GetlastError));
    Result := false;
  end;
end;

end.

Взято с






Как программно двигать курсор мышки?


Как программно двигать курсор мышки?



Следующий пример показывает, как "подтолкнуть мышку" без вмешательства пользователя.

procedure TForm1.Button1Click(Sender: TObject);
var
  pt : TPoint;
begin
   Application.ProcessMessages;
   Screen.Cursor := CrHourglass;
   GetCursorPos(pt);
   SetCursorPos(pt.x + 1, pt.y + 1);
   Application.ProcessMessages;
   SetCursorPos(pt.x - 1, pt.y - 1);
end;

Взято с Исходников.ru



Как программно реализовать Cut, Copy и Paste?


Как программно реализовать Cut, Copy и Paste?



Следущие операции производятся с активным контролом на форме:

procedure TForm1.Cut1Click(Sender: TObject);
begin
  SendMessage (ActiveControl.Handle, WM_Cut, 0, 0);
end;


procedure TForm1.Copy1Click(Sender: TObject);
begin
  SendMessage (ActiveControl.Handle, WM_Copy, 0, 0);
end;

procedure TForm1.Paste1Click(Sender: TObject);
begin
  SendMessage (ActiveControl.Handle, WM_Paste, 0, 0);
end;

Если Вы разрабатываете приложение MDI, то необходимо отправлять сообщение в активное дочернее окно, т.е. использовать: ActiveMDIChild.ActiveControl.Handle

Взято с Исходников.ru