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

  35790931     

Удаление колонки в StringGrid


Удаление колонки в StringGrid



Procedure GridRemoveColumn(StrGrid: TStringGrid; DelColumn: Integer); 
Var Column: Integer; 
begin 
  If DelColumn <= StrGrid.ColCount then 
  Begin 
    For Column := DelColumn To StrGrid.ColCount-1 do 
      StrGrid.Cols[Column-1].Assign(StrGrid.Cols[Column]); 
    StrGrid.ColCount := StrGrid.ColCount-1; 
  End; 
end; 


procedure RemoveColumn(SG : TStringGrid; ColNumber : integer); 
var Column : integer; 
begin 


  ColNumber := abs(ColNumber); 

  if ColNumber <= SG.ColCount then begin 
     for Column := ColNumber to SG.ColCount - 2 do begin 
        SG.Cols[Column].Assign(SG.Cols[Column + 1]); 
        SG.Colwidths[Column] := SG.Colwidths[Column + 1]; 
     end; 
     SG.ColCount := SG.ColCount - 1; 
  end; 
end; 

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



Универсальные пароли к BIOS


Универсальные пароли к BIOS




AWARD BIOS v2.50 
    AWARD_SW
    j262
    TTPTHA
    01322222
    KDD
    ZBAAACA
    aPAf
    lkwpeter
    t0ch88
    t0ch20x
    h6BB
    j09F
    TzqF

AWARD BIOS v2.51 
    AWARD_WG
    j256
    BIOSTAR
    HLT
    ZAAADA
    Syxz
    ?award
    256256
    alfarome
    SWITCHES_SW
    Sxyz
    SZYX
    t0ch20x

AWARD BIOS v2.51G 
    g6PJ
    j322
    ZJAAADC
    Wodj
    bios*
    biosstar
    h6BB
    HELGA-S
    HEWITT
    RAND
    HLT
    t0ch88
    zjaaadc

AWARD BIOS v2.51U 
    1EAAh
    condo
    biostar
    CONDO
    CONCAT
    djonet
    efmukl
    g6PJ
    j09F
    j64
    zbaaaca

AWARD BIOS v4.5x 
    AWARD_SW
    AWARD_PW
    589589
    PASSWORD
    SKY_FOX
    AWARD SW
    award.sw
    AWARD?SW
    award_?
    award_ps
    ZAAADA

AMI BIOS
    AMI 
    AMI_SW (не унивеpсальный но устанавливается пpи сбpосе CMOS/SETUP'a) 
    SER 
    Ctrl+Alt+Del+Ins (держать при загрузке, иногда просто INS) ;) 
    A.M.I. 
    aammii 
    ami.kez 
    ami° 
    amiami 
    AMI!SW 
    AMI.KEY 
    AMI?SW 
    AMISETUP 
    AMI~ 
    AMIPSWD 
    amipswd 
    helgaЯs 
    bios310 
    amidecod 
    BIOSPASS 
    CMOSPWD 
    HEWITT RAND 
    KILLCMOS 

AMPTON BIOS 
    Polrty

AST BIOS 
    SnuFG5

BIOSTAR BIOS 
    Biostar 
    Q54arwms 

COMPAQ BIOS 
    Compaq

CONCORD BIOS 
    last

CTX International BIOS 
    CTX_123

CyberMax BIOS 
    Congress

Daewoo BIOS 
    Daewuu

Daytek BIOS 
    Daytec

DELL BIOS 
    Dell

Digital Equipment BIOS 
    komprie

Enox BIOS 
    xo11nE

Epox BIOS 
    central

Freetech BIOS 
    Posterie

HP Vectra BIOS 
    hewlpack

IBM BIOS 
    IBM 
    MBIUO 
    sertafu 

Iwill BIOS 
    iwill

JetWay BIOS 
    spoom1

Joss Technology BIOS 
    57gbz6 
    technolgi

M Technology BIOS 
    mMmM

MachSpeed BIOS 
    sp99dd

Magic-Pro BIOS 
    prost

Megastar BIOS 
    star

Megastar BIOS 
    sldkj754 
    xyzall 

Micronics BIOS 
    dn_04rjc

Nimble BIOS 
    xdfk9874t3

Packard Bell BIOS 
    bell9

QDI BIOS 
    QDI

Quantex BIOS 
    teX1 
    xljlbj

Research BIOS 
    Col2ogro2

Shuttle BIOS 
    Col2ogro2

Siemens Nixdorf BIOS 
    SKY_FOX

SpeedEasy BIOS 
    lesarot1

SuperMicro BIOS 
    ksdjfg934t

Tinys BIOS 
    tiny

TMC BIOS 
    BIGO

Toshiba BIOS 
    Toshiba 
    24Banc81 
    toshy99

Vextrec Technology BIOS 
    Vextrex

Vobis BIOS 
    merlin

WIMBIOSnbsp v2.10 BIOS 
    Compleri

Zenith BIOS 
    3098z 
    Zenith

ZEOS BIOS 
    zeosx

[C] Faraon

Источник: http://wasm.ru
Прислал p0s0l



Unix-строки (чтение и запись Unix-файлов)


Unix-строки (чтение и запись Unix-файлов)



unitStreamFile;

interface

uses SysUtils;

procedure AssignStreamFile(var F: Text; Filename: string);

implementation

const
  BufferSize = 128;

type
  TStreamBuffer = array[1..High(Integer)] of Char;
  TStreamBufferPointer = ^TStreamBuffer;
  TStreamFileRecord = record
    case Integer of
      1:
      (
        Filehandle: Integer;
        Buffer: TStreamBufferPointer;
        BufferOffset: Integer;
        ReadCount: Integer;
        );
      2:
      (
        Dummy: array[1..32] of Char
        )
  end;

function StreamFileOpen(var F: TTextRec): Integer;
var
  Status: Integer;
begin
  with TStreamFileRecord(F.UserData) do
    begin
      GetMem(Buffer, BufferSize);
      case F.Mode of
        fmInput:
          FileHandle := FileOpen(StrPas(F.Name), fmShareDenyNone);
        fmOutput:
          FileHandle := FileCreate(StrPas(F.Name));
        fmInOut:
          begin
            FileHandle := FileOpen(StrPas(F.Name), fmShareDenyNone or
              fmOpenWrite or fmOpenRead);
            if FileHandle <> -1 then
              status := FileSeek(FileHandle, 0, 2); { Перемещаемся в конец файла. }
            F.Mode := fmOutput;
          end;
      end;
      BufferOffset := 0;
      ReadCount := 0;
      F.BufEnd := 0; { В этом месте подразумеваем что мы достигли конца файла (eof). }
      if FileHandle = -1 then
        Result := -1
      else
        Result := 0;
    end;
end;

function StreamFileInOut(var F: TTextRec): Integer;

  procedure Read(var Data: TStreamFileRecord);
    procedure CopyData;
    begin
      while (F.BufEnd < Sizeof(F.Buffer) - 2)
        and (Data.BufferOffset <= Data.ReadCount)
        and (Data.Buffer[Data.BufferOffset] <> #10) do
        begin
          F.Buffer[F.BufEnd] := Data.Buffer^[Data.BufferOffset];
          Inc(Data.BufferOffset);
          Inc(F.BufEnd);
        end;
      if Data.Buffer[Data.BufferOffset] = #10 then
        begin
          F.Buffer[F.BufEnd] := #13;
          Inc(F.BufEnd);
          F.Buffer[F.BufEnd] := #10;
          Inc(F.BufEnd);
          Inc(Data.BufferOffset);
        end;
    end;

  begin
    F.BufEnd := 0;
    F.BufPos := 0;
    F.Buffer := '';
    repeat
      begin
        if (Data.ReadCount = 0) or (Data.BufferOffset > Data.ReadCount) then
          begin
            Data.BufferOffset := 1;
            Data.ReadCount := FileRead(Data.FileHandle, Data.Buffer^, BufferSize);
          end;
        CopyData;
    end until (Data.ReadCount = 0)
    or (F.BufEnd >= Sizeof(F.Buffer) - 2);
    Result := 0;
  end;

  procedure Write(var Data: TStreamFileRecord);
  var
    Status: Integer;
    Destination: Integer;
    II: Integer;
  begin
    with TStreamFileRecord(F.UserData) do
      begin
        Destination := 0;
        for II := 0 to F.BufPos - 1 do
          begin
            if F.Buffer[II] <> #13 then
              begin
                Inc(Destination);
                Buffer^[Destination] := F.Buffer[II];
              end;
          end;
        Status := FileWrite(FileHandle, Buffer^, Destination);
        F.BufPos := 0;
        Result := 0;
      end;
  end;
begin
  case F.Mode of
    fmInput:
      Read(TStreamFileRecord(F.UserData));
    fmOutput:
      Write(TStreamFileRecord(F.UserData));
  end;
end;

function StreamFileFlush(var F: TTextRec): Integer;
begin
  Result := 0;
end;

function StreamFileClose(var F: TTextRec): Integer;
begin
  with TStreamFileRecord(F.UserData) do
    begin
      FreeMem(Buffer);
      FileClose(FileHandle);
    end;
  Result := 0;
end;

procedure AssignStreamFile(var F: Text; Filename: string);
begin
  with TTextRec(F) do
    begin
      Mode := fmClosed;
      BufPtr := @Buffer;
      BufSize := Sizeof(Buffer);
      OpenFunc := @StreamFileOpen;
      InOutFunc := @StreamFileInOut;
      FlushFunc := @StreamFileFlush;
      CloseFunc := @StreamFileClose;
      StrPLCopy(Name, FileName, Sizeof(Name) - 1);
    end;
end;
end.

Взято из

Советов по Delphi от


Сборник Kuliba





Unresolved external malloc referenced, Ошибка


Unresolved external malloc referenced, Ошибка линкера Kylix 3




Ошибкавозникает на Kilyx 3 (C++ IDE) установленном на новых версиях Linux.

Требуется установить специальный Патч 



Автор:

Vit

Взято из



Управление игрой FreeCell


Управление игрой FreeCell




Если вы решили перепробовать ВСЕ номера игры FreeCell, вас можно квалифицировать как законченного маньяка. В этом случае вас, возможно, заинтересует эта маленькая программка. При ее запуске она загружает FreeCell и начинает игру, следующую за той, которую вы не смогли завершить в прошлый раз. А еще она отвечает на глупые вопросы типа "Do you really want to resign the game?". После выигрыша программа изменяет счетчик таким образом, чтобы при очередном запуске номер игры изменялся на следующий автоматически.

Для создания программы расположите на новой форме таймер, установите ее свойство WindowState на wsMinimized и используйте следующий код:



...
private
{ Private declarations }
  InstHandle: Word;
  WndHandle: hWnd;
  NextGame: Word;

  function EnumFunc(H: HWnd): Word;
  procedure WMQUERYOPEN(var Msg: TWMQueryOpen); message WM_QUERYOPEN;
...

interface
USES
  ShellApi, IniFiles;

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
var
  H, SubH: hMenu;
  NewGameID: Word;
  FreeCellPath: string;
begin
  with TIniFile.Create(ChangeFileExt(Application.ExeName, '.INI')) do
  try
    FreeCellPath := ReadString('FreeCell', 'Path',
      'C:\WIN32APP\FREECELL\FREECELL.EXE') + #0;
    NextGame := ReadInteger('FreeCell', 'NextGame', 1);
  finally
    Free;
  end;
  InstHandle := ShellExecute(Handle, nil, @FreeCellPath[1],
    nil, nil, SW_SHOW);
  WndHandle := 0;
  if InstHandle >= 32 then
    EnumWindows(@TForm1.EnumFunc, LongInt(Self));
  if WndHandle <> 0 then
  begin
    {Вычисляем ID пункта меню "Select Game"}
    H := GetMenu(WndHandle);
    SubH := GetSubMenu(H, 0);
    NewGameID := GetMenuItemID(SubH, 1);
    Winprocs.SetFocus(WndHandle);
    {вызываем "Select Game"}
    PostMessage(WndHandle, WM_COMMAND, NewGameID, 0);
    Timer1.Enabled := True;
  end
  else
    Close;
end;

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

function TForm1.EnumFunc(H: HWnd): Word;
begin

  if GetWindowWord(H, GWW_HINSTANCE) = InstHandle then
  begin
    WndHandle := H;
    Result := 0;
  end
  else
    Result := 1;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
  Buffer: array[0..10] of Char;

  DlgHandle: Word;
begin

  {Если пользователь закрыл FreeCell, выходим!}
  if GetModuleUsage(InstHandle) = 0 then
  begin
    Close;
    Exit;
  end;
  {При необходимости укажите номер игры}
  DlgHandle := FindWindow('#32770', 'Game Number');
  if DlgHandle <> 0 then
  begin
    Str(NextGame, Buffer);
    SendDlgItemMessage(DlgHandle, $CB, WM_SETTEXT,
      0, LongInt(@Buffer));
    PostMessage(DlgHandle, WM_COMMAND, 1,
      MakeLong(GetDlgItem(DlgHandle, 1), BN_CLICKED));
  end;
  {Если игра окончена, увеличиваем счетчик}
  DlgHandle := FindWindow('#32770', 'Game Over');
  if DlgHandle <> 0 then
  begin
    Inc(NextGame);
    with TIniFile.Create(ChangeFileExt(Application.ExeName, '.INI')) do
    try
      WriteInteger('FreeCell', 'NextGame', NextGame);
    finally Free;
    end;
    PostMessage(DlgHandle, WM_COMMAND, 6,
      MakeLong(GetDlgItem(DlgHandle, 6), BN_CLICKED));
  end;
  {Если игра спрашивает, хотите ли вы выйти, отвечем соответственно yes или OK}
  DlgHandle := FindWindow('#32770', 'FreeCell');
  if DlgHandle <> 0 then
  begin
    if (not (GetDlgItemText(DlgHandle, 6, Buffer, 10) in [0, 10]))
      and (StrComp(Buffer, '&Yes') = 0) then
      PostMessage(DlgHandle, WM_COMMAND, 6,
        MakeLong(GetDlgItem(DlgHandle, 6), BN_CLICKED))
    else if (not (GetDlgItemText(DlgHandle, 2, Buffer, 10) in [0, 10]))
      and (StrComp(Buffer, 'Cancel') = 0) then
      PostMessage(DlgHandle, WM_COMMAND, 1,
        MakeLong(GetDlgItem(DlgHandle, 1), BN_CLICKED))
  end;
end;



Взято с





Управление настройками шрифта


Управление настройками шрифта




{
Данныйкод изменяет стиль шрифта поля редактирования,
если оно выбрано. Может быть адаприрован для управления
шрифтами в других объектах.

Расположите на форме Edit(Edit1) и ListBox(ListBox1).
Добавьте следующие элементы (Items) к ListBox:
fsBold
fsItalic
fsUnderLine
fsStrikeOut
}

procedure TForm1.ListBox1Click(Sender: TObject);
var
  X: Integer;
type
  TLookUpRec = record
    Name: string;
    Data: TFontStyle;
  end;
const
  LookUpTable: array[1..4] of TLookUpRec =
  ((Name: 'fsBold'; Data: fsBold),
    (Name: 'fsItalic'; Data: fsItalic),
    (Name: 'fsUnderline'; Data: fsUnderline),
    (Name: 'fsStrikeOut'; Data: fsStrikeOut));
begin
  X := ListBox1.ItemIndex;
  Edit1.Text := ListBox1.Items[X];
  Edit1.Font.Style := [LookUpTable[ListBox1.ItemIndex + 1].Data];
end;

Взято из





Управление приложением через Telnet


Управление приложением через Telnet




Итак, начнем с главного - почему для удаленного администрирования своей программы следует использовать именно Telnet? Ответ на этот вопрос достаточно прост:

Утилита Telnet есть на любом компьютере с операционной системой Windows, UNIX, AIX и т.п., поэтому ее не требуется писать или устанавливать
Telnet является штатным средством удаленного администрирования.
Telnet подразумевает текстовый обмен, поэтому его очень легко поддерживать в своей программе
Возможностей текстового терминала как правило достаточно для управления программой, ее настройки и администрирования
Рассмотрим немного теории. Утилиту Telnet легче всего запустить через Start->Run (Пуск -> Выполнить). После запуска необходимо произвести соединение с удаленным хостом, для чего выполняется используется меню "Connect->Remote System". При этом выводится меню соединения, в котором необходимо указать три параметра: хост, порт и тип терминала. В качестве хоста указывается имя удаленного компьютера (или его IP адрес), порт можно задать двумя путями - выбором/вводом символического имени (например, telnet), или вводом номера порта. Мы будем пользоваться вторым путем, т.е. будем использовать нестандартные номера портов. Тип терминала оставим vt100.

Утилита Telnet поддерживает параметры командой строки:

telnet [remote_host] [port]

где

remote_host представляет собой имя или IP адрес удаленной машины.
port номер порта. Если соединение идет по стандартному порту, то этот параметр опускается.
Пример:

telnet zaitsevov или telnet zaitsevov 5000

Протокол Telnet очень прост - сначала устанавливается TCP/IP соединение с удаленной машиной. Затем, когда пользователь вводит символ, происходит его передача удаленному хосту. Для простоты будем называть его сервером.

Далее возможно два режима работы - с локальным эхом или без локального эха (режим по умолчанию). Если работа ведется с локальным эхом, то каждый вводимый пользователем символ немедленно отображается на экране. При работе без локального эха сервер обязан создавать эхо, дублирую принимаемые данные клиенту. Это позволят тестировать канал (каждый символ проходит по кругу) и организовывать ввод данных без эха (например, для ввода пароля). Мои примеры ориентированы на работу без локального эха.

При приеме любой информации от сервера утилита Telnet немедленно отображает его на экране. Это позволяет серверу организовывать эхо и выводить любую информацию в текстовом виде. При этом поддерживатся некоторые управляющие коды, например, код "забой", стирающий один символ.

Итак, приступим к разработке приложения. Создадим пустой проект и поместим на форму компонент ServerSocket1 типа TServerSocket. Зададим ему порт, например 5000. Напоминаю, что:

номер порта должен быть нестандартным, чтобы не пересекаться с другими программами. При этом желательно считывать его из INI файла, что даст возможность настройки при необходимости.
Свойство Active должно быть false и устанавливаться в true при запуске программы. Иначе приложение свалится при попытке запуска второй копии или при отсутствии сети. Установку Active := true следует делать в блоке try ... except
Итак, в обработчике OnCreate формы пишем:

begin
try
    ServerSocket1.Active := true;
  except
    ShowMessage('Ошибки при активации ServerSocket');
  end;
end;

Далее необходимо научиться определять моменты соединения и отключения клиента. Для этого следует создать обработчики OnClientConnect и OnClientDisconnect. Сразу отмечу, что при подключении клиента обычно принято выдывать ему заголовок, ообщающий о том, что он соединился с программой *** версии NN. С учетом этого обработчик OnClientConnect будет иметь вид:

procedure TMain.ServerSocket1ClientConnect(Sender: TObject; Socket: TCustomWinSocket);
begin
  Socket.SendText('Connected. Программа Telnet1 Example на проводе.'+#$0D+#$0A);
  Socket.SendText('Enter password : ');
  Connected := false;
  Memo1.Lines.Add('Произошло соединение с пользователем');
end;

При этом я хочу подчеркнуть особенность - нормально поддерживается одно соединение, для нескольких необходимы некоторые усложнения и мых их пока опустим.

Особенности:

Выводить информацию при соединении желательно на английском языке. Это позволяет избежать ситуации, когда на компьтере администратора не окажется поддержки русского языка и Telnet выведет ему абракадабру. У меня это наблюдается постоянно на английской NT 4 - приходится каждый раз лазить в настройки Telnet и задавать русский CharSet.
При соединении следует спросить пароль. Иначе каждый, кому нечего делать, залезет в программу и будет там ковыряться (из практики - преценденты были).
Переменная Connected отмечает, что пользователь еще не соединился с программой (т.е. не провел свою идентификацию). Рассмотрим сразу обработчик OnClientDisconnect, он еще проще:

// Поддержка связи по TCP/IP для удаленного конфигурирования - действия при отключении
procedure TMain.ServerSocket1ClientDisconnect(Sender: TObject; Socket: TCustomWinSocket);
begin
  Connected := false;
  Memo1.Lines.Add('Соединение разорвано');
end;

Итак, теперь настало время для самого интересного - написания обработчика OnClientRead. Этот обработчик вызывается всякий раз, когда от клиента приходят данные. Т.е. в свете приведенных выше теоретических замечаний это будет происходить при вводе каждого отдельного символа. Задачи обработчика:

Создавать (при необходимости) эхо для всех принимаемых символов. Очевидно, что при вводе паролей эхо создавать не нужно. При созании эха необходимо учитывать, что символ с кодом FF (буква "я") должен повторяться дважды, иначе он будет погложен Telnet - ом как служебный и не отобразится
Накапливать вводимые символы, ожидая прихода признака конца команы. Как правило, признаком конца команды считают перевод код строки (следует заметить, что тут разработчик сам себе стандарт, но отклоняться от общепринятых правил не рекомендуется. Для накопления принимаемой информации стоит завести буферную переменную, в моем случае она будет называться TelnetS.
При получении символа с кодом 08h ("BackSpace") необходимо не помещать ее в буфер, а стереть из буфера последний символ. Но в виде эха его отправить необходимо, т.к. это приведет к стиранию символа на экране Telnet (при подавлении эха он останется на экране, но сотрется в буфере программы, что приведет к путанице).
При обнаружении символа перевода строки (код $0D) следует считать содержимое буфера командой и интерпретировать. Как - это отдельный разговор
Все вышеописанное реализует примерно следующий код:

// Поддержка связи по TCP/IP для удаленного конфигурирования - действия при получении данных
procedure TForm1.ServerSocket1ClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
  s, st: string;
begin
  s := Socket.ReceiveText;

  // Это код перевода строки ? Если да, то выполняем команду и передаем ее ответ клиенту
  if ord(s[1]) = $0D then
  begin
    st := ExecuteCMD(TelnetS);
    if st <> '' then
      st := #$0D + #$0A + st;
    st := st + #$0D + #$0A + '>';
    TelnetSendText(Socket, st);
    TelnetS := '';
    exit;
  end;

  // Это код клавиши BackSpace. Если да, то передадим его клиенту
  // и удалим последний символ из буфера
  if ord(s[1]) = $08 then
  begin
    Delete(TelnetS, length(TelnetS), 1);
    TelnetSendText(Socket, s);
    exit;
  end;

  // Добавим очередной символ к буферу
  TelnetS := TelnetS + s;

  // Передадим его клиенту для организации эха
  if connected then
    TelnetSendText(Socket, s);
end;

Как легко заметить, приведенный выше код реализует эхо, обрабатывает BackSpace и дожидается ввода команды, считая код $OD (Enter) признаком завершения ввода команды. При обнаружении этого кода вызывается функция пользователя ExecuteCMD, которая должна разобрать и проанализировать команду, выполнить ее и вернуть (при необходомости) ответ пользователю. Эта же функция занимается проверкой вводимого пользователем пароля. Так ка передача ответа/эха имеет некоторые особенности, например, необходимость удвоения символа с кодом FF и подавления передачи для реализации невидимого ввода, имеет смысл выполнить ее в виде отдельной функции:

// Передача ответа/эха клиенту
function TForm1.TelnetSendText(Socket: TCustomWinSocket; AText: string): boolean;
var
  i: integer;
  St: string;
begin
  Result := false;
  if not(connected) then
    exit;
  St := '';
  for i := 1 to length(AText) do
    if AText[i] <> #$FF then
      st := st + AText[i]
    else
      st := st + #$FF + #$FF;
  Socket.SendText(st);
end;

// В моем примере функция ExecuteCMD имеет вид:
// Интерретатор команд
function TForm1.ExecuteCMD(ACmd: string): string;
var
  UCmd, Params: string;
begin
  Result := '';
  Memo1.Lines.Add('Выполняется: '+ACmd);
  if not(connected) then
  begin
    if UpperCase(ACmd) = '123' then
    begin
      Connected := true;
      Result := 'Пользователь идентифицирован!';
    end;
    exit;
  end;

  // Выделение команды
  UCmd := ACmd;
  Params := '';
  if pos(' ', UCmd) > 0 then
  begin
    Params := Copy(UCmd, pos(' ', UCmd)+1, Length(UCmd));
    UCmd := Copy(UCmd, 1, pos(' ', UCmd)-1);
  end;
  UCmd := Trim(UpperCase(UCMD));
  Memo1.Lines.Add('Выделена команда: '+UCmd);

  // ? или HLP или HELP - вывод справки
  if (UCmd = '?') or (UCmd = 'HLP') or (UCmd = 'HELP') then
  begin
    Result :=
    'Краткая справка по командам Telnet интерфейса'+CRLF+
    ' ?, HLP, HELP - вызов справки'+CRLF+
    ' EXIT - завершение работы по Telnen интерфейсу'+CRLF+
    ' HALT - немедленный останов программы'+CRLF+
    ' VER - версия программы'+CRLF+
    ' MESS <собщение> - вывод сообщения для пользователя'+CRLF+
    ' INP <собщение> - вывод сообщения для пользователя и возврат его ответа';
    exit;
  end;

  if (UCmd = 'EXIT') then
  begin
    ServerSocket1.Socket.Connections[0].Close;
    exit;
  end;

  if (UCmd = 'VER') then
  begin
    Result := 'Версия 1.00 от 27.01.2001 (C) Зайцев Олег';
    exit;
  end;

  if (UCmd = 'HALT') then
    halt;

  if (UCmd = 'MESS') then
  begin
    ShowMessage(Params);
    exit;
  end;

  if (UCmd = 'INP') then
  begin
    Result := InputBox(Params,'Введите ответ', '');
    exit;
  end;

  Result := 'Неизвестная команда ' + ACmd;
end;

Реальная система команд естественно определяется разработчиком, но рекомендуется предусмотреть следующие команды:

?, HLP, HELP для вывода справочной информации (практика показала, что при поддерке 20-30 команд больше половины забываются за месяц)
EXIT - завершение обмена
И, наконец, в завершении следует отметить одну особенность - пользователь может завершить обмен корректно (путем ввода команды EXIT (если таковая поддерживается) или выбором опции "Отключить" в Telnet; и некорректно - путем закрытия Telnet во время обмена. В этом случае в программе будет ошибка сокета 10054. Ее имеет смысл поймать и подавить при помощи обработчика OnClientError следующего вида:

procedure TForm1.ServerSocket1ClientError(Sender: TObject; Socket: TCustomWinSocket;
  ErrorEvent: TErrorEvent; var ErrorCode: Integer);
begin
  // Обработка события "разрыв соединения"
  if ErrorCode = 10054 then
  begin
    Socket.Close;
    ErrorCode := 0;
  end;
end;

И в завершении хочется сказать, что подобная система внедрена в несколько моих программ, испрользуемых в ОАО Смоленскэнерго и отлично себя зарекомендовала, т.к. предприятие большое и возможность удаленной настройки/управления в ряде случаев освобождает разработчика от ненужной беготни.


Взято с






Управление транзакциями


Управление транзакциями



Each function listed below begins, ends, or inquires about the status of a transaction.



DbiBeginTran:
Begins a transaction.

DbiEndTran:
Ends a transaction.

DbiGetTranInfo:
Retrieves the transaction state.


Взято с

Delphi Knowledge Base




Управляющие коды принтера


Управляющие коды принтера




Как мне послать на принтер управляющие коды принтера(Printer Control Codes)без перевода их в непечатные символы? Наверняка без Windows API в Delphi не обойтись.Когда я передаю управляющие коды принтера, они печатаются как непечатные символы, а не воспринимаются принтером как управляющие коды.

Вам нужно использовать Escape функцию принтера Passthrough, чтобы переслать данные непосредственно в принтер.В случае использования функции WriteLn это, конечно, не работает.Вот некоторый код, чтобы уговорить вас начать:

unitPassthru;

interface

uses printers, WinProcs, WinTypes, SysUtils;

procedure PrintTest;

implementation

type

  TPassThroughData = record
    nLen: Integer;
    Data: array[0..255] of byte;
  end;

procedure DirectPrint(s: string);
var

  PTBlock: TPassThroughData;
begin

  PTBlock.nLen := Length(s);
  StrPCopy(@PTBlock.Data, s);
  Escape(printer.handle, PASSTHROUGH, 0, @PTBlock, nil);
end;

procedure PrintTest;
begin

  Printer.BeginDoc;
  DirectPrint(CHR(27) + '&l1O' + 'Привет, Вася!');
  Printer.EndDoc;
end;

end.

Взято из

Советов по Delphi от


Сборник Kuliba






After compiling and installing Apache


Using a DSO on Apache 2.0.43, created with Kylix 3



After compiling and installing Apache 2.0.39 with DSO support, deploying an .so file built with Kylix 3 doesn't work.

You need to change MODULE_MAGIC_NUMBER_MAJOR in HTTPD.pas file to the following: MODULE_MAGIC_NUMBER_MAJOR = 20020903;

Using Tapi


Using Tapi



How can I use TAPI to dial the telephone for a voice call?

The following example shows how to interface with tapi to make a
voice call.

{tapi Errors}
 const TAPIERR_CONNECTED          = 0;
 const TAPIERR_DROPPED            = -1;
 const TAPIERR_NOREQUESTRECIPIENT = -2;
 const TAPIERR_REQUESTQUEUEFULL   = -3;
 const TAPIERR_INVALDESTADDRESS   = -4;
 const TAPIERR_INVALWINDOWHANDLE  = -5;
 const TAPIERR_INVALDEVICECLASS   = -6;
 const TAPIERR_INVALDEVICEID      = -7;
 const TAPIERR_DEVICECLASSUNAVAIL = -8;
 const TAPIERR_DEVICEIDUNAVAIL    = -9;
 const TAPIERR_DEVICEINUSE        = -10;
 const TAPIERR_DESTBUSY           = -11;
 const TAPIERR_DESTNOANSWER       = -12;
 const TAPIERR_DESTUNAVAIL        = -13;
 const TAPIERR_UNKNOWNWINHANDLE   = -14;
 const TAPIERR_UNKNOWNREQUESTID   = -15;
 const TAPIERR_REQUESTFAILED      = -16;
 const TAPIERR_REQUESTCANCELLED   = -17;
 const TAPIERR_INVALPOINTER       = -18;

{tapi size constants}
 const TAPIMAXDESTADDRESSSIZE      = 80;
 const TAPIMAXAPPNAMESIZE          = 40;
 const TAPIMAXCALLEDPARTYSIZE      = 40;
 const TAPIMAXCOMMENTSIZE          = 80;
 const TAPIMAXDEVICECLASSSIZE      = 40;
 const TAPIMAXDEVICEIDSIZE         = 40;

function tapiRequestMakeCallA(DestAddress : PAnsiChar;
                              AppName : PAnsiChar;
                              CalledParty : PAnsiChar;
                              Comment : PAnsiChar) : LongInt;
  stdcall; external 'TAPI32.DLL';

function tapiRequestMakeCallW(DestAddress : PWideChar;
                              AppName : PWideChar;
                              CalledParty : PWideChar;
                              Comment : PWideChar) : LongInt;
  stdcall; external 'TAPI32.DLL';

function tapiRequestMakeCall(DestAddress : PChar;
                             AppName : PChar;
                             CalledParty : PChar;
                             Comment : PChar) : LongInt;
  stdcall; external 'TAPI32.DLL';

procedure TForm1.Button1Click(Sender: TObject);
var
  DestAddress : string;
  CalledParty : string;
  Comment : string;
begin
  DestAddress := '1-555-555-1212';
  CalledParty := 'Frank Borland';
  Comment := 'Calling Frank';
  tapiRequestMakeCall(pChar(DestAddress),
                      PChar(Application.Title),
                      pChar(CalledParty),
                      PChar(Comment));

end;

end.



Using the Shell API function SHBrowseForFolder


Using the Shell API function SHBrowseForFolder



uses ShellAPI, ShlObj;

procedure TForm1.Button1Click(Sender: TObject);
var
  TitleName : string;
  lpItemID : PItemIDList;
  BrowseInfo : TBrowseInfo;
  DisplayName : array[0..MAX_PATH] of char;
  TempPath : array[0..MAX_PATH] of char;
begin
  FillChar(BrowseInfo, sizeof(TBrowseInfo), #0);
  BrowseInfo.hwndOwner := Form1.Handle;
  BrowseInfo.pszDisplayName := @DisplayName;
  TitleName := 'Please specify a directory';
  BrowseInfo.lpszTitle := PChar(TitleName);
  BrowseInfo.ulFlags := BIF_RETURNONLYFSDIRS;
  lpItemID := SHBrowseForFolder(BrowseInfo);
  if lpItemId  nil then begin
    SHGetPathFromIDList(lpItemID, TempPath);
    ShowMessage(TempPath);
    GlobalFreePtr(lpItemID);
  end;
end;




Using Visual Basic arrays in Delphi


Using Visual Basic arrays in Delphi



How do I pass arrays from VB to Delphi?

Arrays can be passed as variants:

VB module code:
Attribute VB_Name = "Module1"
Declare Function TestMin Lib "c:\windows\system\NoelSArr" 
   (Nums As Variant) As Integer

VB form code:
Dim A As Variant
Private Sub Command1_Click()
  A = Array(4, 3)
  MsgBox (TestMin(A))
End Sub

Delphi DLL code:
library NoelSArray;
.
.
function TestMin(const Nums: Variant): integer; export; stdcall;
var
 p1: Variant;
begin
 p1 := VarArrayCreate([0, 1], VT_I4);
 p1:= Nums;
  if (p1[0] < p1[1]) then
   result:= p1[0]
 else
   Result:= p1[1];
end;



Ускорение работы TreeView


Ускорение работы TreeView




Представляем вашему вниманию немного переработанный компонент TreeView, работающий быстрее своего собрата из стандартной поставки Delphi. Кроме того, была добавлена возможность вывода текста узлов и пунктов в жирном начертании (были использованы методы TreeView, хотя, по идее, необходимы были свойства TreeNode. Мне показалось, что это будет удобнее).

Для сравнения:

TreeView:

128 сек. для загрузки 1000 элементов (без сортировки)*
270 сек. для сохранения 1000 элементов (4.5 минуты!!!)
HETreeView:

1.5 сек. для загрузки 1000 элементов - ускорение около 850%!!! (2.3 секунды без сортировки = stText)*
0.7 сек. для сохранения 1000 элементов - ускорение около 3850%!!!
Примечание:


Все операции выполнялись на медленной машине 486SX 33 Mгц, 20 Mб RAM.
Если TreeView пуст, загрузка происходит за 1.5 секунды, плюс 1.5 секунды на стирание 1000 элементов (общее время загрузки составило 3 секунды). В этих условиях стандартный компонент TTreeView показал общее время 129.5 секунд. Очистка компонента осуществлялась вызовом функции SendMessage(hwnd, TVM_DELETEITEM, 0, Longint(TVI_ROOT)).
Проведите несколько приятных минут, развлекаясь с компонентом.



unitHETreeView;
{$R-}

// Описание: Реактивный TreeView
(*

TREEVIEW:
128 сек. для загрузки 1000 элементов (без сортировки)*
270 сек. для сохранения 1000 элементов (4.5 минуты!!!)

HETREEVIEW:
1.5 сек. для загрузки 1000 элементов - ускорение около 850%!!!
  (2.3 секунды без сортировки = stText)*
0.7 сек. для сохранения 1000 элементов - ускорение около 3850%!!!

NOTES:
- Все операции выполнялись на медленной машине 486SX 33 Mгц, 20 Mб RAM.

- * Если TTreeView пуст, загрузка происходит за 1.5 секунды,
плюс 1.5 секунды на стирание 1000 элементов
  (общее время загрузки составило 3 секунды).
В этих условиях стандартный компонент TreeView показал общее время 129.5 секунд.
Очистка компонента осуществлялась вызовом функции
SendMessage(hwnd, TVM_DELETEITEM, 0, Longint(TVI_ROOT)).
*)

interface

uses

  SysUtils, Windows, Messages, Classes, Graphics,
  Controls, Forms, Dialogs, ComCtrls, CommCtrl;

type

  THETreeView = class(TTreeView)
  private
    FSortType: TSortType;
    procedure SetSortType(Value: TSortType);
  protected
    function GetItemText(ANode: TTreeNode): string;
  public
    constructor Create(AOwner: TComponent); override;
    function AlphaSort: Boolean;
    function CustomSort(SortProc: TTVCompare; Data: Longint): Boolean;
    procedure LoadFromFile(const AFileName: string);
    procedure SaveToFile(const AFileName: string);
    procedure GetItemList(AList: TStrings);
    procedure SetItemList(AList: TStrings);
    //Жирное начертание шрифта 'Bold' должно быть свойством TTreeNode, но...
    function IsItemBold(ANode: TTreeNode): Boolean;
    procedure SetItemBold(ANode: TTreeNode; Value: Boolean);
  published
    property SortType: TSortType read FSortType write SetSortType default
      stNone;
  end;

procedure Register;

implementation

function DefaultTreeViewSort(Node1, Node2: TTreeNode; lParam: Integer): Integer;
  stdcall;
begin

  {with Node1 do
  if Assigned(TreeView.OnCompare) then
  TreeView.OnCompare(Node1.TreeView, Node1, Node2, lParam, Result)
  else}
  Result := lstrcmp(PChar(Node1.Text), PChar(Node2.Text));
end;

constructor THETreeView.Create(AOwner: TComponent);
begin

  inherited Create(AOwner);
  FSortType := stNone;
end;

procedure THETreeView.SetItemBold(ANode: TTreeNode; Value: Boolean);
var

  Item: TTVItem;
  Template: Integer;
begin

  if ANode = nil then
    Exit;

  if Value then
    Template := -1
  else
    Template := 0;
  with Item do
  begin
    mask := TVIF_STATE;
    hItem := ANode.ItemId;
    stateMask := TVIS_BOLD;
    state := stateMask and Template;
  end;
  TreeView_SetItem(Handle, Item);
end;

function THETreeView.IsItemBold(ANode: TTreeNode): Boolean;
var

  Item: TTVItem;
begin

  Result := False;
  if ANode = nil then
    Exit;

  with Item do
  begin
    mask := TVIF_STATE;
    hItem := ANode.ItemId;
    if TreeView_GetItem(Handle, Item) then
      Result := (state and TVIS_BOLD) <> 0;
  end;
end;

procedure THETreeView.SetSortType(Value: TSortType);
begin

  if SortType <> Value then
  begin
    FSortType := Value;
    if ((SortType in [stData, stBoth]) and Assigned(OnCompare)) or
      (SortType in [stText, stBoth]) then
      AlphaSort;
  end;
end;

procedure THETreeView.LoadFromFile(const AFileName: string);
var

  AList: TStringList;
begin

  AList := TStringList.Create;
  Items.BeginUpdate;
  try
    AList.LoadFromFile(AFileName);
    SetItemList(AList);
  finally
    Items.EndUpdate;
    AList.Free;
  end;
end;

procedure THETreeView.SaveToFile(const AFileName: string);
var

  AList: TStringList;
begin

  AList := TStringList.Create;
  try
    GetItemList(AList);
    AList.SaveToFile(AFileName);
  finally
    AList.Free;
  end;
end;

procedure THETreeView.SetItemList(AList: TStrings);
var

  ALevel, AOldLevel, i, Cnt: Integer;
  S: string;
  ANewStr: string;
  AParentNode: TTreeNode;
  TmpSort: TSortType;

  function GetBufStart(Buffer: PChar; var ALevel: Integer): PChar;
  begin
    ALevel := 0;
    while Buffer^ in [' ', #9] do
    begin
      Inc(Buffer);
      Inc(ALevel);
    end;
    Result := Buffer;
  end;

begin

  // Удаление всех элементов - в обычной ситуации
  // подошло бы Items.Clear, но уж очень медленно
  SendMessage(handle, TVM_DELETEITEM, 0, Longint(TVI_ROOT));
  AOldLevel := 0;
  AParentNode := nil;

  //Снятие флага сортировки
  TmpSort := SortType;
  SortType := stNone;
  try
    for Cnt := 0 to AList.Count - 1 do
    begin
      S := AList[Cnt];
      if (Length(S) = 1) and (S[1] = Chr($1A)) then
        Break;

      ANewStr := GetBufStart(PChar(S), ALevel);
      if (ALevel > AOldLevel) or (AParentNode = nil) then
      begin
        if ALevel - AOldLevel > 1 then
          raise Exception.Create('Неверный уровень TreeNode');
      end
      else
      begin
        for i := AOldLevel downto ALevel do
        begin
          AParentNode := AParentNode.Parent;
          if (AParentNode = nil) and (i - ALevel > 0) then
            raise Exception.Create('Неверный уровень TreeNode');
        end;
      end;
      AParentNode := Items.AddChild(AParentNode, ANewStr);
      AOldLevel := ALevel;
    end;
  finally
    //Возвращаем исходный флаг сортировки...
    SortType := TmpSort;
  end;
end;

procedure THETreeView.GetItemList(AList: TStrings);
var

  i, Cnt: integer;
  ANode: TTreeNode;
begin

  AList.Clear;
  Cnt := Items.Count - 1;
  ANode := Items.GetFirstNode;
  for i := 0 to Cnt do
  begin
    AList.Add(GetItemText(ANode));
    ANode := ANode.GetNext;
  end;
end;

function THETreeView.GetItemText(ANode: TTreeNode): string;
begin

  Result := StringOfChar(' ', ANode.Level) + ANode.Text;
end;

function THETreeView.AlphaSort: Boolean;
var

  I: Integer;
begin

  if HandleAllocated then
  begin
    Result := CustomSort(nil, 0);
  end
  else
    Result := False;
end;

function THETreeView.CustomSort(SortProc: TTVCompare; Data: Longint): Boolean;
var

  SortCB: TTVSortCB;
  I: Integer;
  Node: TTreeNode;
begin

  Result := False;
  if HandleAllocated then
  begin
    with SortCB do
    begin
      if not Assigned(SortProc) then
        lpfnCompare := @DefaultTreeViewSort
      else
        lpfnCompare := SortProc;
      hParent := TVI_ROOT;
      lParam := Data;
      Result := TreeView_SortChildrenCB(Handle, SortCB, 0);
    end;

    if Items.Count > 0 then
    begin
      Node := Items.GetFirstNode;
      while Node <> nil do
      begin
        if Node.HasChildren then
          Node.CustomSort(SortProc, Data);
        Node := Node.GetNext;
      end;
    end;
  end;
end;

//Регистрация компонента

procedure Register;
begin

  RegisterComponents('Win95', [THETreeView]);
end;

end.



Взято с





Установка BDE


Установка BDE



Cодержание раздела:









Установка Interbase и добавление пользователя


Установка Interbase и добавление пользователя




Автор: Denis Alexandrovich Ivanov


Как сделать инсталятор, который прописывал бы пользователя в Interbase? BDE при этом не нужна совсем.

1. При помощи InstallShieldExpress формируется проект, который включает в себя установку Interbase Server.
2. После установки Interbase запускаешь программу, написанную на Delphi 6, которая добавляет нового пользователя Interbase



{************************************************************************
Проект: ....
Автор        : Иванов Д.А.
Назначение   : Выжимки из библиотеки функций для работы со справочником
               пользователей
               Note: You must install InterBase 6 to use this feature.
Дата создания: 11.13.2002
История      :
************************************************************************}
unit usr;
interface
uses IBCustomDataSet,IBDataBase,IBServices;
type
  TUsrInfo = record
    Usr:string ; //login
    Uid:integer; //уникальный идентификатор, если программа ведет
                 //справочник пользователей в своей БД - его можно
                 //брать оттуда по секвенции
    Grp:integer; //Group
    Pas:string ; //password
  end;

  TUsrClass = class(TObject)
  private
    { Private declarations }
  public
    UsrData:TUsrInfo;
    dbSec  :TIBSecurityService;
    // добавляет или редактирует пользователя в Interbase
    function UpdateUser: string;
  end;

  TUsrLib = class(TUsrClass)
  private
    { Private declarations }
  public
    procedure AddNewUserToInterbase;
  end;

var
  clUsr:TUsrLib;

implementation
uses SysUtils,Controls,db,windows,QDialogs;

(***************** Добавляет или редактирует пользователя ***************)
function TUsrClass.UpdateUser: string;
                               //Usrid = 0 - новый пользователь
  var Edes:string; //Описание ошибок
begin
  try
    if UsrData.Usr = '' then Edes:= 'не указан login пользователя';
    if UsrData.Uid = 0  then Edes:= 'не указан id пользователя';
    if UsrData.Grp = 0  then Edes:= 'не 
    if UsrData.Pas = '' then Edes:= 'не указан пароль пользователя';
    if EDes < >  '' then raise Exception.Create(Edes);
    //Добавляем пользователя в interbase
    with dbSec do begin
      if not Active then Active := True;
      UserName  := UsrData.Usr;
      UserID    := UsrData.Uid;
      GroupID   := UsrData.Grp;
      Password  := UsrData.Pas;
      try
        DisplayUser(UserName);
        if UserInfo[0] = nil then AddUser else ModifyUser;
      except
        Edes:='Ошибка добавления пользователя в interbase security';
        raise Exception.Create(Edes);
      end;
      //раздача если нужно права доступа пользователя на таблицы
      (* EDes:= GrantData(UsrData.Usr);
         if EDes < >  '' then raise Exception.Create(Edes);
      *)
    end;
  except
    if EDes = '' then EDes:= 'Ошибка добавления пользователя в interbase security';
  end;
  Result:= EDes;
end;

procedure TUsrLib.AddNewUserToInterbase;
  var Edes:string; //Описание ошибок
begin
  UsrData.Usr := 'ida' ;
  UsrData.Uid := 123   ;
  UsrData.Grp := 1     ;
  UsrData.Pas := 'pass';
  EDes:= UpdateUser;
  if EDes < >  '' then raise Exception.Create(Edes);
end;

begin
  clUsr:=TUsrLib.Create;
end.




Установку Interbase 6.0 я пробовал делать двумя системами создания инсталляций:

- InstallShield
- Wise Install Builder.

Для обоих использовал готовые скрипты с сайта http://ibinstall.defined.net/. По результатам могу сказать, что Wise удобнее и проще в инсталляции. Кроме того у него есть текстовый редактор скрипта, что нашему брату шибко нравится. Установка и запуск IBGuard проходит как и в фирменном варианте сразу (Silent Install).

Взято из





Установка каретки в RichEdit


Установка каретки в RichEdit



Узнать положение курсора в RichEdit не составляет труда (richedit.getcaret). А вот как установить каретку в нужное место ?.

Procedure setline(WhichEdit:TRichedit;Linepos,charpos:integer);
Begin
with WhichEdit do  
begin  
  selstart:=perform(EM_LineIndex,Linenum,0)+charpos;  
  perform(EM_ScrollCaret,0,0);  
end;  
end;

Комментарии:
Если Вам не нужно, чтобы происходил скроллинг к позиции каретки, то EM_ScrollCaret можно убрать. Эта процедура так же может быть использована для TMemo, только надо будет заменить объявление witchedit на TMemo:
Procedure CustomMemoSetline(WhichEdit:TCustomMemo;Linepos,charpos:integer);

Так же эту процедуру можно использовать как ответ на вопрос "Как установить фокус на определённую строку в компоненте Memo ?". Для этого необходимо добавить следующий код после строки selstart:
sellength:=length(lines(line));
И установить charpos в 0.

RichEdit должен иметь фокус, иначе em_ScrollCaret не сработает.

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



Установка ODBC


Установка ODBC





Автор: Johannes M. Becher (CODATA GmbH Krefeld, Germany)

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

A) ODBCINST.INI - описание всех установленных драйверов ODBC

Секция [ODBC Drivers] в каждой строчке описывает один драйвер. Здесь прописано формальное имя драйвера, использующегося позже для идентификации драйвера.

Каждый драйвер, как вы увидите позже, имеет собственную секцию, к примеру, вот секция для Watcom :

{1} [Watcom SQL 4.0]
{2} Driver=D:\WIN31\SYSTEM\WOD40W.DLL
{3} Setup=D:\WIN31\SYSTEM\WOD40W.DLL
Строка 1 содержит имя секции драйвера из [ODBC Drivers].
Строка 2 сообщает Windows о том, где следует искать DLL, содержащую методы, применяемые ODBC для доступа к базам данных Watcom.
Строка 3 сообщает Windows о том, где следует искать DLL, содержащую методы, применяемые ODBC для административных целей.
Все, что имеется в файле ODBCINST.INI - теперь содержится в файле #2 (таком же легком для изучения):

B) ODBC.INI - описание всех ваших баз данных (источников данных, говоря языком ODBC)

Секция [ODBC Data Sources] в каждой строчке описывает одну базу данных; формат:
{описание базы данных} = {описание драйвера из ODBCINST.INI}
Данный файл сообщает ODBC, к каким базам данных вы хотите иметь доступ и какой драйвер для каждой конкретной базы данных для этого необходим.

Каждая база данных, как вы увидите позже, имеет собственную секцию, к примеру, вот секция PB Demo:


{1} [Powersoft Demo DB=Watcom SQL 4.0]
{2} DatabaseFile=E:\PB4\EXAMPLES\PSDEMO.DB
{3} DatabaseName=PSDEMODB
{4} UID=dba
{5} PWD=sql
{6} Driver=D:\WIN31\SYSTEM\WOD40W.DLL
{7} Start=D:\WSQL40\DBSTARTW -d -c512
Строка 1 содержит ссылку на секцию [ODBC Data Sources].
Строка 2 содержит физический путь к файлу базы данных.
Строка 3 - описание, только для вашего чтения.
Строка 4 - User ID, которое Watcom применяет для установления связи.
Строка 5 - Пароль, используемый для установления соединения.
- Это не очень секретно; если вы оставите эту строку пустой, Watcom сам спросит пароль при получении доступа к базе данных.
Строка 6 содержит имя драйвера (снова - сравните с OBDCINST.INI)
Строка 7 содержит имя движка базы данных для ее запуска (это необходимо лишь для баз данных SQL, например, в версии Client / Server).
Все это может быть отредактировано как вручную (в любом текстовом редакторе), так и в ODBCADM (ODBC Administration). Что касается меня лично, то я более не использую ODBCADM; я ощущаю себя гораздо лучше, если имею больший контроль над INI-файлами, редактируя строки вручную.

Структура секций в файле ODBC.INI может отличаться для разных драйверов, поэтому вам необходимо научиться ориентироваться по ключевым словам, описанным выше.

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

Взято с





UUE кодирование


UUE кодирование




Автор: Sergei Dubarev

Для того, чтобы ОНО заработало, необходимо создать проект в составе:

Форма (form) - 1 шт.
Поле ввода (edit) - 2 шт., используются события OnDblClick.
Кнопка (button) - 1 шт., используется событие OnClick.
Диалог открытия файла (Open Dialog) - 1 шт.
Диалог сохранения файла (Save Dialog) - 1 шт.
Имена файлов будут вводится либо вручную, либо из диалога (double-click на поле ввода edit), причем в edit1.text должно лежать имя входного файла, в edit2.text - выходного. По нажатии кнопки пойдет процесс, который завершится сообщением "DONE."
Всего хорошего.

P. S. Функция toanysys обнаружена в книге "Для чего нужны и как работают персональные ЭВМ" от 1990 г. Там она присутствует в виде программы на BASIC'e.

P.P.S. Для стимулирования фантазии читателей "Советов..." высылаю так же мессагу из эхи, на основе которой я сваял свое чудо.

Файл Unit1.pas



//UUEкодирование
unit Unit1;

interface

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

type

  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Edit2: TEdit;
    OpenDialog1: TOpenDialog;
    SaveDialog1: TSaveDialog;
    procedure Edit1DblClick(Sender: TObject);
    procedure Edit2DblClick(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

const

  ssz = (High(Cardinal) - $F) div sizeof(byte);
  //эта константа используется при выделении памяти

  p: string = '0123456789ABCDEF';
  //эта константа используется функцией toanysys

  //выбор входного файла

procedure TForm1.Edit1DblClick(Sender: TObject);
begin

  if opendialog1.execute then
    edit1.text := opendialog1.filename;
end;

//выбор выходного (UUE) файла

procedure TForm1.Edit2DblClick(Sender: TObject);
begin

  if savedialog1.execute then
    edit2.text := savedialog1.filename;
end;

//выделение подстроки

function mid(s: string; fromc, toc: byte): string;
var
  s1: string;

  i: byte;
begin

  s1 := '';
  for i := fromc to toc do
    s1 := s1 + s[i];
  mid := s1;
end;

//перевод числа (a) из десятичной системы в другую
//с основанием (r)

function toanysys(a, r: byte): string;
var
  s,

  k: string;
  n,
    m,
    i: byte;
begin

  s := '';
  m := 1;
  while m <> 0 do
  begin
    m := a div r;
    n := a - m * r + 1;
    k := p[n];
    s := k + s;
    a := m;
  end;
  //добавляет незначащие нули
  for i := 1 to 8 - length(s) do
    s := '0' + s;
  toanysys := s;
end;

//перевод 6-разрядного числа из двоичной системы в десятичную
//двоичное число подставляется в виде строки символов

function frombin(s: string): byte;
var
  i,

  e,
    b: byte;
begin

  b := 0;
  for i := 1 to 6 do
  begin
    e := 1 shl (6 - i);
    if s[i] = '1' then
      b := b + e;
  end;
  frombin := b;
end;

//непосредственно кодирование
type
  tcoola = array[1..1] of byte;
  pcoola = ^tcoola;

procedure TForm1.Button1Click(Sender: TObject);
var
  inf: file of byte;

  ouf: textfile;
  uue: pcoola;
  b: array[1..4] of byte;
  bin,
    t: string;
  szf,
    oum,
    szl,
    szh,
    sxl,
    sxh,
    i,
    j: longint;
begin

{$I-}
  assignfile(inf, edit1.text); //входной файл
  reset(inf);
  szf := filesize(inf); //
  szh := (szf * 8) div 6; //
  if szf * 8 - szh * 6 = 0 then
    szl := 0
  else
    szl := 1; //
  getmem(uue, szh + szl); //выделение памяти
  oum := 1;
  while not (eof(inf)) do
  begin
    b[1] := 0;
    b[2] := 0;
    b[3] := 0;
    b[4] := 0;
    //чтение должно быть сделано посложнее,
    //дабы избежать "read beyond end of file"
    read(inf, b[1], b[2], b[3]);
    //читаем 3 байта из входного файла
    //и формируем "двоичную" строку
    bin := toanysys(b[1], 2) +
      toanysys(b[2], 2) +
      toanysys(b[3], 2);
    //разбиваем строку на куски по 6 бит и добавляем 32
    t := mid(bin, 19, 24);
    b[4] := frombin(t) + 32;
    t := mid(bin, 13, 18);
    b[3] := frombin(t) + 32;
    t := mid(bin, 07, 12);
    b[2] := frombin(t) + 32;
    t := mid(bin, 01, 06);
    b[1] := frombin(t) + 32;
    //запихиваем полученнные байты во временный массив
    uue[oum] := b[1];
    oum := oum + 1;
    uue[oum] := b[2];
    oum := oum + 1;
    uue[oum] := b[3];
    oum := oum + 1;
    uue[oum] := b[4];
    oum := oum + 1;
  end;
  //входной файл больше не нужен - закрываем его
  closefile(inf);
  //формируем выходной файл
  assignfile(ouf, edit2.text); //выходной файл
  rewrite(ouf);
  oum := 1;
  sxh := (szh + szl) div 60; //число строк в UUE файле
  sxl := (szh + szl) - sxh * 60;
  //заголовок UUE-файла
  writeln(ouf, 'begin 644 ' + extractfilename(edit1.text));
  //записываем строки в файл
  for i := 1 to sxh do
  begin
    write(ouf, 'M');
    // 'M' значит, что в строке 60 символов
    for j := 1 to 60 do
    begin
      write(ouf, chr(uue[oum]));
      oum := oum + 1;
    end;
    writeln(ouf);
  end;
  //записываем последнюю строку, которая
  //обычно короче 60 символов
  sxh := (sxl * 6) div 8;
  write(ouf, chr(sxh + 32));
  for i := 1 to sxl do
  begin
    write(ouf, chr(uue[oum]));
    oum := oum + 1;
  end;
  // "добиваем" строку незначащими символами
  for i := sxl + 1 to 60 do
    write(ouf, '`');
  //записываем последние строки файла
  writeln(ouf);
  writeln(ouf, '`');
  writeln(ouf, 'end');
  closefile(ouf);
  freemem(uue, szh + szl); //освобождаем память
  showmessage('DONE.'); //Готово. Забирайте!
end;

end.





1) Читаем из исходного хфайла 3 байта.
2) Разбиваем полyченные 24 бита (8x3=24) на 4 части, т.е. по 6 бит.
3) Добавляем к каждой части число 32 (десятичн.)

Пpимеp: Имеем тpи числа 234 12 76. Побитово бyдет так -

11101010 00001100 01001100 pазбиваем и полyчаем -

111010 100000 110001 001100 добавляем 32 -
+100000 +100000 +100000 +100000
------ ------ ------ ------
1011010 1000000 1010001 101100 или в бyквах -
Z @ Q ,

Вот собственно и все. В UUE файле в пеpвой позиции стоит кол-во закодиpованных
символов + 32. Т.е. вся стpока содеpжит 61 символ. 1 символ идет на кол-во.
Остается 60 символов _кода_. Если подсчитать, то мы yвидим, что для полyчения
60
символов кода необходимо 45 исходных символов. Для полной стpоки в начале стоит

бyква "M", а ее ASCII код = 77. 45+32=77.


Взято с





В чем отличие между Create(Self) и Create(Application)?


В чем отличие между Create(Self) и Create(Application)?




Self может быть использовано только в методе класса, и ссылается на текущий экземпляр класса. Таким образом "Self" в методе класса TForm1 ссылается на текущий экземпляр TForm1. При создании компонента Вы передаете его владельца (owner) в конструктор. При уничтожении формы или компонента автоматически уничтожаются и все компоненты владельцем которого она является. Таким образом если при создании формы передать в качестве владельца Application эта форма будет автоматически уничтожена при уничтожении Application. Если же при создании формы передать в качестве владельца другую форму, вновь созданная форма будет автоматически уничтоженна при уничтожении формы-владельца.




В чем разница между CHAR и VARCHAR ? Что лучше использовать?


В чем разница между CHAR и VARCHAR ? Что лучше использовать?




Разработчики утверждают, что разницы практически нет - особенности VARCHAR в том, что используется дополнительно два байта для хранения длины, а CHAR игнорирует пробелы в конце хранимой строки.

Если вы собираетесь хранить строки длиной не более 40-50 символов, то лучше использовать CHAR. Более подробно см. статью.

При передаче по сети в текущих версиях IB VARCHAR передается так-же как и CHAR (т.е. неэффективно). Исправлено в IB 5.0.


Borland Interbase / Firebird FAQ
Borland Interbase / Firebird Q&A, версия 2.02 от 31 мая 1999
последняя редакция от 17 ноября 1999 года.
Часто задаваемые вопросы и ответы по Borland Interbase / Firebird
Материал подготовлен в Демо-центре клиент-серверных технологий. (Epsylon Technologies)
Материал не является официальной информацией компании Borland.
E-mail mailto:delphi@demo.ru
www: http://www.ibase.ru/
Телефоны: 953-13-34
источники: Borland International, Борланд АО, релиз Interbase 4.0, 4.1, 4.2, 5.0, 5.1, 5.5, 5.6, различные источники на WWW-серверах, текущая переписка, московский семинар по Delphi и конференции, листсервер ESUNIX1, листсервер mers.com.
Cоставитель: Дмитрий Кузьменко




В InterBase при создании базы ввести параметр для поддержки русского языка


В InterBase при создании базы ввести параметр для поддержки русского языка





UPDATERDB$FIELDS 
SET RDB$CHARACTER_SET_ID = 52 
WHERE RDB$FIELD_NAME = 'RDB$SOURCE''


Взято из





В каком порядке происходят события при создании и показе окна?


В каком порядке происходят события при создании и показе окна?





При создании окна обработчики событий выполняются в следующем порядке:

OnCreate
   OnShow
   OnPaint
   OnActivate
   OnResize
   OnPaint (снова)


Copyright © 1996 Epsylon Technologies


Взято из

FAQ Epsylon Technologies (095)-913-5608; (095)-913-2934; (095)-535-5349




В основном Help'е в Delphi не работает индекс по Win32?


В основном Help'е в Delphi не работает индекс по Win32?



- в /help/delphi3.cfg добавить строку типа
:index Win32=Win32.hlp
она должна быть добавлена перед строкой
:Link win32.hlp
- стереть delphi3.gid
- запустить Help и получать удовольствие

В delphi3.cnt тоже нужно строчку добавить:
:include win32.cnt

Взято с сайта



VCL


VCL



Cодержание раздела:


·
·  
·  
·  
·  
·  
·  
·  
·  
·  
·  
·  


·  
·  
·  
·  
·  
 


·
·  
·  
·  
 


·  
·  
·  
·  
·  
·  
 


·
·  
·  
·  
·  
·  
·  
 


·  
·  
·  
·  
·  


·

(раздел)

·

(раздел)

·

(раздел)

·

(раздел)

·

(раздел)

·

(раздел)

·

(раздел)

·

(раздел)


·  
·  


·


·  
·  
·  
·  
·  
·  
·  
·  
·  
·  


·
·  
·  
·  
·  
·  
·  
·  
·  
·  
·  
·  
·  
·  


·  
·  
·  
·  
·  
·  
·  
·  
·  
·  
·  
·  
 


·
·  
·  
·  
 


·  
·  


·
·  
·  
·  
·  
·  
·  
·  
·  
·  
·  
·  
·  
·  
·  


·  
·  
·  
·  
·  
·  
·  
·  
·  
·  



·
·  
·  
·  
·  
·  
·  
·  
·  
·  
·  
·  
·  
·  
·  


·  
·  
·  
·  
·  
·  


·  
·  
·  
·  
·  
·  


·  


·  
·  
·  
·  
·  
·  
·  
·  
·  
·  
·  
·  
·  


·  
·  
·  
·  
·  
 


·
·  
·  
·  
·  
·  
·  
·  
·  


·  
·  
·  


·
 


·  
·  
·  
·  
·  
·  
·  
·  
·  


·
·  
·  
·  
·  
·  
·  
·  
·  
·  
·  



·  
 


·
·  


·  



·



См. также другие разделы:





См. также статьи в других разделах:





Вертикальный текст


Вертикальный текст




var
Hfont: Thandle;
  logfont: TLogFont;
  font: Thandle;
  count: integer;
begin
  LogFont.lfheight := 30;
  logfont.lfwidth := 10;
  logfont.lfweight := 900;
  LogFont.lfEscapement := -200;
  logfont.lfcharset := 1;
  logfont.lfoutprecision := out_tt_precis;
  logfont.lfquality := draft_quality;
  logfont.lfpitchandfamily := FF_Modern;
  font := createfontindirect(logfont);
  Selectobject(Form1.canvas.handle, font);
  SetTextColor(Form1.canvas.handle, rgb(0, 0, 200));
  SetBKmode(Form1.canvas.handle, transparent);
  {textout(form1.canvas.handle,10,10,'Повернутый',7);}
  for count := 1 to 100 do
  begin
    canvas.textout(Random(form1.width), Random(form1.height), 'Повернутый');
    SetTextColor(form1.canvas.handle, rgb(Random(255), Random(255),
      Random(255)));
  end;
  deleteobject(font);
end;

Взято из





Видоизменяем чекбоксы в Delphi


Видоизменяем чекбоксы в Delphi



В WIN3.1 чекбоксы заполняются символом "X". В WIN95 и WINNT - символом "V". В тандартной палитре Delphi чекбоксы заполняются символом "X". Спрашивается - почему фирма Borland/Inprise не исправила значёк чекбокса для W95/W98 ?. Данный пример позволяет заполнять чекбокс такими значками как: "X", "V", "o", "закрашенным прямоугольником", или бриллиантиком.

Пример тестировался под WIN95 и WINNT.


==================================================================== 
                          Обозначения
==================================================================== 
X = крестик
V = галочка 
o = кружок 

+-+ 
|W| = заполненный прямоугольник 
+-+ 

/\ 
= бриллиантик 
\/ 

==================================================================== 
                  Преимущества этого чекбокса 
==================================================================== 
Вы можете найти множество чекбоксов в интернете. Но у них есть недостаток, они не обрабатывают сообщение WM_KILLFOCUS. Приведённый ниже пример делает это. 
==================================================================== 

Unit CheckBoxX; 

Interface 

Uses 
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, 
  Dialogs, StdCtrls; 

Const 
   { другие константы } 
   fRBoxWidth  : Integer = 13; // ширина квадрата checkbox 
   fRBoxHeight : Integer = 13; // высота квадрата checkbox 

Type 
  TState = (cbUnchecked,cbChecked,cbGrayed); // такой же как в Delphi 
  TType = (cbCross,cbMark,cbBullet,cbDiamond,cbRect); // добавленный 
  TMouseState = (msMouseUp,msMouseDown); 
  TAlignment = (taRightJustify,taLeftJustify); // The same 

  TCheckBoxX = class(TCustomControl) 

  Private 
    { Private declarations } 
    fChecked        : Boolean; 
    fCaption        : String; 
    fColor          : TColor; 
    fState          : TState; 
    fFont            : TFont; 
    fAllowGrayed    : Boolean; 
    fFocus          : Boolean; 
    fType            : TType; 
    fMouseState     : TMouseState; 
    fAlignment      : TAlignment; 
    fTextTop        : Integer;  // отступ текта с верху 
    fTextLeft       : Integer;  // отступ текта с лева 
    fBoxTop         : Integer;  // координата чекбокса сверху 
    fBoxLeft        : Integer;  // координата чекбокса слева 

    Procedure fSetChecked(Bo : Boolean); 
    Procedure fSetCaption(S : String); 
    Procedure fSetColor(C : TColor); 
    Procedure fSetState(cbState : TState); 
    Procedure fSetFont(cbFont : TFont); 
    Procedure fSetAllowGrayed(Bo : Boolean); 
    Procedure fSetType(T : TType); 
    Procedure fSetAlignment(A : TAlignment); 

  Protected 
    { Protected declarations } 
    Procedure Paint; override; 
    Procedure MouseDown(Button: TMouseButton; Shift: TShiftState; 
      X, Y: Integer); override; 
    Procedure MouseUp(Button: TMouseButton; Shift: TShiftState; 
      X, Y: Integer); override; 
    Procedure WMKillFocus(var Message : TWMKillFocus); 
      Message WM_KILLFOCUS; // это убирает контур фокуса! 
    Procedure WMSetFocus(var Message : TWMSetFocus); 
      Message WM_SETFOCUS; // Если вы используете клавишу TAB или Shift-Tab 
    Procedure KeyDown(var Key : Word; Shift : TShiftState); override; 
      // перехват KeyDown 
    Procedure KeyUp(var Key : Word; Shift : TShiftState); override; 
      // перехват KeyUp 

  Public 
    { Public declarations } 
    // Если поместить Create и Destroy в раздел protected, 
    // то Delphi начинает ругаться. 
    Constructor Create(AOwner : TComponent); override; 
    Destructor Destroy; override; 

  Published 
    { Published declarations } 
    { --- Свойства --- } 
    Property Action; 
    Property Alignment : TAlignment 
       read fAlignment write fSetAlignment; 
    Property AllowGrayed : Boolean 
       read fAllowGrayed write fSetAllowGrayed; 
    Property Anchors; 
    Property BiDiMode; 
    Property Caption : String 
       read fCaption write fSetCaption; 
    Property CheckBoxType : TType 
       read fType write fSetType; 
    Property Checked : Boolean 
       read fChecked write fSetChecked; 
    Property Color : TColor 
       read fColor write fSetColor; 
    Property Constraints; 
    //Property Ctrl3D; 
    Property Cursor; 
    Property DragCursor; 
    Property DragKind; 
    Property DragMode; 
    Property Enabled; 
    Property Font : TFont 
       read fFont write fSetFont; 
    //Property Height; 
    Property HelpContext; 
    Property Hint; 
    Property Left; 
    Property Name; 
    //Property PartenBiDiMode; 
    Property ParentColor; 
    //Property ParentCtrl3D; 
    Property ParentFont; 
    Property ParentShowHint; 
    //Property PopMenu; 
    Property ShowHint; 
    Property State : TState 
       read fState write fSetState; 
    Property TabOrder; 
    Property TabStop; 
    Property Tag; 
    Property Top; 
    Property Visible; 
    //Property Width; 
    { --- Events --- } 
    Property OnClick; 
    Property OnContextPopup; 
    Property OnDragDrop; 
    Property OnDragOver; 
    Property OnEndDock; 
    Property OnEndDrag; 
    Property OnEnter; 
    Property OnExit; 
    Property OnKeyDown; 
    Property OnKeyPress; 
    Property OnKeyUp; 
    Property OnMouseDown; 
    Property OnMouseMove; 
    Property OnMouseUp; 
    Property OnStartDock; 
    Property OnStartDrag; 
  End; 

Procedure Register; //Hello! 

Implementation 

{-------------------------------------------------------------------} 
Procedure TCheckBoxX.KeyDown(var Key : Word; Shift : TShiftState); 

Begin 
If fFocus then 
   If Shift = [] then 
      If Key = 0032 then 
         Begin 
         fMouseState := msMouseDown; 
         If fState <> cbGrayed then 
            Begin 
            SetFocus; // Устанавливаем фокус на этот компонент 
                      // всем другим компонентам Windows посылает сообщение WM_KILLFOCUS. 
            fFocus := True; 
            Invalidate; 
            End; 
         End; 
Inherited KeyDown(Key,Shift); 
End; 
{-------------------------------------------------------------------} 
Procedure TCheckBoxX.KeyUp(var Key : Word; Shift : TShiftState); 

Begin 
If fFocus then 
   If Shift = [] then 
      If Key = 0032 then 
         Begin 
         If fState <> cbGrayed then 
            fSetChecked(not fChecked); // Изменяем состояние 
         fMouseState := msMouseUp; 
         End; 
Inherited KeyUp(Key,Shift); 
End; 
{-------------------------------------------------------------------} 
Procedure TCheckBoxX.WMSetFocus(var Message : TWMSetFocus); 

Begin 
fFocus := True; 
Invalidate; 
End; 
{-------------------------------------------------------------------} 
Procedure TCheckBoxX.WMKillFocus(var Message : TWMKillFocus); 

Begin 
fFocus := False; // Удаляем фокус у всех компонент, которые не имеют фокуса. 
Invalidate; 
End; 
{-------------------------------------------------------------------} 
Procedure TCheckBoxX.fSetAlignment(A : TAlignment); 

Begin 
If A <> fAlignment then 
   Begin 
   fAlignment := A; 
   Invalidate; 
   End; 
End; 
{-------------------------------------------------------------------} 
Procedure TCheckBoxX.fSetType(T : TType); 

Begin 
If fType <> T then 
   Begin 
   fType := T; 
   Invalidate; 
   End; 
End; 
{-------------------------------------------------------------------} 
Procedure TCheckBoxX.fSetFont(cbFont : TFont); 

Var 
   FontChanged : Boolean; 

Begin 
FontChanged := False; 

If fFont.Style <> cbFont.Style then 
   Begin 
   fFont.Style := cbFont.Style; 
   FontChanged := True; 
   End; 

If fFont.CharSet <> cbFont.Charset then 
   Begin 
   fFont.Charset := cbFont.Charset; 
   FontChanged := True; 
   End; 

If fFont.Size <> cbFont.Size then 
   Begin 
   fFont.Size := cbFont.Size; 
   FontChanged := True; 
   End; 

If fFont.Name <> cbFont.Name then 
   Begin 
   fFont.Name := cbFont.Name; 
   FontChanged := True; 
   End; 

If fFont.Color <> cbFont.Color then 
   Begin 
   fFont.Color := cbFont.Color; 
   FontChanged := True; 
   End; 

If FontChanged then 
   Invalidate; 
End; 
{-------------------------------------------------------------------} 
procedure TCheckBoxX.MouseDown(Button: TMouseButton; Shift: TShiftState; 
  X, Y: Integer); 

Begin 
// Процедура MouseDown вызывается, когда кнопка мышки нажимается в пределах 
// кнопки, соответственно мы не можем получить значения координат X и Y. 
inherited MouseDown(Button, Shift, X, Y); 
fMouseState := msMouseDown; 
If fState <> cbGrayed then 
   Begin 
   SetFocus; // Устанавливаем фокус на этот компонент 
             // всем другим компонентам Windows посылает сообщение WM_KILLFOCUS. 
   fFocus := True; 
   Invalidate; 
   End; 
End; 
{-------------------------------------------------------------------} 
procedure TCheckBoxX.MouseUp(Button: TMouseButton; Shift: TShiftState; 
  X, Y: Integer); 

Begin 
// Процедура MouseUp вызывается, когда кнопка мышки отпускается в пределах 
// кнопки, соответственно мы не можем получить значения координат X и Y. 
inherited MouseUp(Button, Shift, X, Y); 
If fState <> cbGrayed then 
   fSetChecked(not fChecked); // Изменяем состояние 
fMouseState := msMouseUp; 
End; 
{-------------------------------------------------------------------} 
Procedure TCheckBoxX.fSetAllowGrayed(Bo : Boolean); 

Begin 
If fAllowGrayed <> Bo then 
   Begin 
   fAllowGrayed := Bo; 
   If not fAllowGrayed then 
      If fState = cbGrayed then 
         Begin 
         If fChecked then 
            fState := cbChecked 
         else 
            fState := cbUnChecked; 
         End; 
   Invalidate; 
   End; 
End; 
{-------------------------------------------------------------------} 
Procedure TCheckBoxX.fSetState(cbState : TState); 

Begin 
If fState <> cbState then 
   Begin 
   fState := cbState; 
   If (fState = cbChecked) then 
      fChecked := True; 

   If (fState = cbGrayed) then 
      fAllowGrayed := True; 

   If fState = cbUnChecked then 
      fChecked := False; 

   Invalidate; 
   End; 
End; 
{-------------------------------------------------------------------} 
Procedure TCheckBoxX.fSetColor(C : TColor); 

Begin 
If fColor <> C then 
   Begin 
   fColor := C; 
   Invalidate; 
   End; 
End; 
{-------------------------------------------------------------------} 
Procedure TCheckBoxX.fSetCaption(S : String); 

Begin 
If fCaption <> S then 
   Begin 
   fCaption := S; 
   Invalidate; 
   End; 
End; 
{-------------------------------------------------------------------} 
Procedure TCheckBoxX.fSetChecked(Bo : Boolean); 

Begin 
If fChecked <> Bo then 
   Begin 
   fChecked := Bo; 
   If fState <> cbGrayed then 
      Begin 
      If fChecked then 
         fState := cbChecked 
      else 
         fState := cbUnChecked; 
      End; 
   Invalidate; 
   End; 
End; 
{-------------------------------------------------------------------} 
procedure TCheckBoxX.Paint;

var
  Buffer: array[0..127] of Char;
  I: Integer;
  fTextWidth, fTextHeight: Integer;

begin
{Get Delphi's componentname and initially write it in the caption}
  GetTextBuf(Buffer, SizeOf(Buffer));
  if Buffer <> '' then
    fCaption := Buffer;

  Canvas.Font.Size := Font.Size;
  Canvas.Font.Style := Font.Style;
  Canvas.Font.Color := Font.Color;
  Canvas.Font.Charset := Font.CharSet;

  fTextWidth := Canvas.TextWidth(fCaption);
  fTextHeight := Canvas.TextHeight('Q');

  if fAlignment = taRightJustify then
    begin
      fBoxTop := (Height - fRBoxHeight) div 2;
      fBoxLeft := 0;
      fTextTop := (Height - fTextHeight) div 2;
      fTextLeft := fBoxLeft + fRBoxWidth + 4;
    end
  else
    begin
      fBoxTop := (Height - fRBoxHeight) div 2;
      fBoxLeft := Width - fRBoxWidth;
      fTextTop := (Height - fTextHeight) div 2;
      fTextLeft := 1;
   //If fTextWidth > (Width - fBoxWidth - 4) then
   //   fTextLeft := (Width - fBoxWidth - 4) -  fTextWidth;
    end;

// выводим текст в caption
  Canvas.Pen.Color := fFont.Color;
  Canvas.Brush.Color := fColor;
  Canvas.TextOut(fTextLeft, fTextTop, fCaption);

// Рисуем контур фокуса
  if fFocus = True then
    Canvas.DrawFocusRect(Rect(fTextLeft - 1,
      fTextTop - 2,
      fTextLeft + fTextWidth + 1,
      fTextTop + fTextHeight + 2));

  if (fState = cbChecked) then
    Canvas.Brush.Color := clWindow;

  if (fState = cbUnChecked) then
    Canvas.Brush.Color := clWindow;

  if (fState = cbGrayed) then
    begin
      fAllowGrayed := True;
      Canvas.Brush.Color := clBtnFace;
    end;

// Создаём бокс clBtnFace когда кнопка мыши нажимается
// наподобие "стандартного" CheckBox
  if fMouseState = msMouseDown then
    Canvas.Brush.Color := clBtnFace;

  Canvas.FillRect(Rect(fBoxLeft + 2,
    fBoxTop + 2,
    fBoxLeft + fRBoxWidth - 2,
    fBoxTop + fRBoxHeight - 2));

// Рисуем прямоугольный чекбокс
  Canvas.Brush.Color := clBtnFace;
  Canvas.Pen.Color := clGray;
  Canvas.MoveTo(fBoxLeft + fRBoxWidth - 1, fBoxTop);
  Canvas.LineTo(fBoxLeft, fBoxTop);
  Canvas.LineTo(fBoxLeft, fBoxTop + fRBoxHeight);

  Canvas.Pen.Color := clWhite;
  Canvas.MoveTo(fBoxLeft + fRBoxWidth - 1, fBoxTop);
  Canvas.LineTo(fBoxLeft + fRBoxWidth - 1,
    fBoxTop + fRBoxHeight - 1);
  Canvas.LineTo(fBoxLeft - 1, fBoxTop + fRBoxHeight - 1);

  Canvas.Pen.Color := clBlack;
  Canvas.MoveTo(fBoxLeft + fRBoxWidth - 3, fBoxTop + 1);
  Canvas.LineTo(fBoxLeft + 1, fBoxTop + 1);
  Canvas.LineTo(fBoxLeft + 1, fBoxTop + fRBoxHeight - 2);

  Canvas.Pen.Color := clBtnFace;
  Canvas.MoveTo(fBoxLeft + fRBoxWidth - 2, fBoxTop + 1);
  Canvas.LineTo(fBoxLeft + fRBoxWidth - 2,
    fBoxTop + fRBoxHeight - 2);
  Canvas.LineTo(fBoxLeft, fBoxTop + fRBoxHeight - 2);

// Теперь он должен быть таким же как чекбокс в Delphi

  if fChecked then
    begin
      Canvas.Pen.Color := clBlack;
      Canvas.Brush.Color := clBlack;

   // Рисуем прямоугольник
      if fType = cbRect then
        begin
          Canvas.FillRect(Rect(fBoxLeft + 4, fBoxTop + 4,
            fBoxLeft + fRBoxWidth - 4, fBoxTop + fRBoxHeight - 4));
        end;

   // Рисуем значёк "о"
      if fType = cbBullet then
        begin
          Canvas.Ellipse(fBoxLeft + 4, fBoxTop + 4,
            fBoxLeft + fRBoxWidth - 4, fBoxTop + fRBoxHeight - 4);
        end;

   // Рисуем крестик
      if fType = cbCross then
        begin
      {Right-top to left-bottom}
          Canvas.MoveTo(fBoxLeft + fRBoxWidth - 5, fBoxTop + 3);
          Canvas.LineTo(fBoxLeft + 2, fBoxTop + fRBoxHeight - 4);
          Canvas.MoveTo(fBoxLeft + fRBoxWidth - 4, fBoxTop + 3);
          Canvas.LineTo(fBoxLeft + 2, fBoxTop + fRBoxHeight - 3);
          Canvas.MoveTo(fBoxLeft + fRBoxWidth - 4, fBoxTop + 4);
          Canvas.LineTo(fBoxLeft + 3, fBoxTop + fRBoxHeight - 3);
      {Left-top to right-bottom}
          Canvas.MoveTo(fBoxLeft + 3, fBoxTop + 4);
          Canvas.LineTo(fBoxLeft + fRBoxWidth - 4,
            fBoxTop + fRBoxHeight - 3);
          Canvas.MoveTo(fBoxLeft + 3, fBoxTop + 3);
          Canvas.LineTo(fBoxLeft + fRBoxWidth - 3,
            fBoxTop + fRBoxHeight - 3); //mid
          Canvas.MoveTo(fBoxLeft + 4, fBoxTop + 3);
          Canvas.LineTo(fBoxLeft + fRBoxWidth - 3,
            fBoxTop + fRBoxHeight - 4);
        end;

   // Рисуем галочку
      if fType = cbMark then
        for I := 0 to 2 do
          begin
         {Left-mid to left-bottom}
            Canvas.MoveTo(fBoxLeft + 3, fBoxTop + 5 + I);
            Canvas.LineTo(fBoxLeft + 6, fBoxTop + 8 + I);
         {Left-bottom to right-top}
            Canvas.MoveTo(fBoxLeft + 6, fBoxTop + 6 + I);
            Canvas.LineTo(fBoxLeft + 10, fBoxTop + 2 + I);
          end;

   // Рисуем бриллиантик
      if fType = cbDiamond then
        begin
          Canvas.Pixels[fBoxLeft + 06, fBoxTop + 03] := clBlack;
          Canvas.Pixels[fBoxLeft + 06, fBoxTop + 09] := clBlack;

          Canvas.MoveTo(fBoxLeft + 05, fBoxTop + 04);
          Canvas.LineTo(fBoxLeft + 08, fBoxTop + 04);

          Canvas.MoveTo(fBoxLeft + 05, fBoxTop + 08);
          Canvas.LineTo(fBoxLeft + 08, fBoxTop + 08);

          Canvas.MoveTo(fBoxLeft + 04, fBoxTop + 05);
          Canvas.LineTo(fBoxLeft + 09, fBoxTop + 05);

          Canvas.MoveTo(fBoxLeft + 04, fBoxTop + 07);
          Canvas.LineTo(fBoxLeft + 09, fBoxTop + 07);

          Canvas.MoveTo(fBoxLeft + 03, fBoxTop + 06);
          Canvas.LineTo(fBoxLeft + 10, fBoxTop + 06); // middle line
        end;
    end;
end;

{-------------------------------------------------------------------} 
procedure Register;
begin
  RegisterComponents('Samples', [TCheckBoxX]);
end;
{-------------------------------------------------------------------}

destructor TCheckBoxX.Destroy;

begin
  inherited Destroy;
end;
{-------------------------------------------------------------------}

constructor TCheckBoxX.Create(AOwner: TComponent);

begin
  inherited Create(AOwner);
  Height := 17;
  Width := 97;
  fChecked := False;
  fColor := clBtnFace;
  fState := cbUnChecked;
  fFont := inherited Font;
  fAllowGrayed := False;
  fFocus := False;
  fMouseState := msMouseUp;
  fAlignment := taRightJustify;
  TabStop := True; // Sorry
end;
{-------------------------------------------------------------------}
end.
{===================================================================}


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



Virtual ListView с контекстным меню


Virtual ListView с контекстным меню



В Delphi5/Demos есть пример Virtual ListView. программка чем-то напоминает explorer, но без контекстного меню. контекстное меню приделывается так:

procedure TForm1.PopupMenu1Popup(Sender: TObject);
var
ContextMenu : IContextMenu;  
menu : HMENU;  
begin
FIShellFolder.GetUIObjectOf(Handle, 1, ShellItem(ListView.Selected.Index).ID,  
IID_IContextMenu, nil, ContextMenu);  
menu := CreatePopupMenu();  
ContextMenu.QueryContextMenu(menu, 0, 1, $7FFF, CMF_EXPLORE);  
TrackPopupMenu(menu,  
TPM_LEFTALIGN or TPM_LEFTBUTTON or TPM_RIGHTBUTTON or TPM_RETURNCMD,  
Mouse.CursorPos.x, Mouse.CursorPos.y, 0, Handle, nil);  
DestroyMenu(menu);  
end;

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



Визуальные компоненты для DB


Визуальные компоненты для DB



Итак, мы не написав ни строчки кода получили простейшее приложение, работающее с базой данных. С помощью него мы можем просматривать и редактировать содержимое таблицы. Давайте теперь сделаем эту процедуру немного удобнее, на закладке "Data Control" есть компонент TDBNavigator. Положим его на форму и в инспекторе объектов поставим его свойство DataSource указывающим на тот же DataSource1, что и для DBGrid - собственно, теперь оба визуальных контрола(DBGrid и DBNavigator) привязаны к одному и тому же DataSource и через него к одной и той же таблицы. DBNavigator имеет несколько кнопок (вы можете настроить какие именно вы хотите видеть) дающие лёгкий контроль над следующими операциями:
(перечисление в порядке расположения кнопок)
1)Переход на первую запись  
2)Переход на предыдущую запись  
3)Переход на следующую запись  
4)Переход на последнюю запись  
5)Добавить запись  
6)Удалить запись  
7)Редактировать запись  
8)Сохранить изменения  
9)Отменить изменения  
10)Перечитать таблицу  
 
Обратите внимание, что запись (строка) таблицы есть как бы неделимый квант информации - т.е. отменяются действия произведенные для всей записи целиком, добавляется или удаляется тоже строка целиком.

Разберём ещё несколько визуальных компонентов, чтобы покончить с визуализацией данных и перейти собственно к программированию.

На закладке Data Controls есть ещё несколько важных компонентов, давайте поставим их на нашу форму: DBLabel, DBEdit, DBMemo и DBImage. Все их так же как и DBGrid соединим с DataSource1. Однако здесь мы обнаружим что этого недостаточно, эти компоненты работают с отдельной ячейкой в таблице, поэтому мы должны указать ещё поле (столбец) который они будут показывать.
Давайте сделаем следуюшие - для каждого из этих компонентов укажем свойство DataField, например следующим образом:

DBLabel - ассоциируем с полем Category
DBEdit - ассоциируем с полем Common_name
DBMemo - ассоциируем с полем Notes
DBImage - ассоциируем с полем Graphic

Можно откомпилировать программу и немного поиграться с ней. Итак что мы можем здесь увидеть? Что в каждый данный момент времени из всей таблицы у нас есть запись которая активная (текущая) - в DBGrid она показывается треугольничком слева. Именно с этой единственной записью мы и можем оперировать - удалять, добавлять, редактировать, именно её содержимое отображается в DBLabel, DBEdit, DBMemo, DBImage и именно она может быть изменена при помощи этих компонентов. Описанная только что структура позволяет работать только с одной записью в определённый момент времени, если вы переходите на другую запись то все изменения должны быть либо запомнены либо отменены! По умолчанию они запоминаются без всяких запросов, в чём вы можете убедиться меняя значения и переходя на другую запись.




Включение и выключение устройств ввода/вывода


Включение и выключение устройств ввода/вывода




Иногда может возникнуть необходимость в выключении на время устройств ввода - клавиатуры и мыши. Например, это неплохо сделать на время выполнения кода системы защиты от копирования, в играх, или в качестве "наказания" при запуске программы по истечению срока ее бесплатного использования ... . Однако наилучшее ее применение - отключение клавиатуры и мыши на время работы демонстрационки, основанной на воспроизведении записанных заранее перемещений мышки и клавиатурного ввода (см. об этом отдельный раздел этой книги). Это элементарно сделать при помощи API:
EnableHadwareInput(Enable:boolean): boolean;
Enable - требуемое состояние устройств ввода (True - включены, false - выключены). Если ввод заблокирован, то его можно разблокировать вручную - нажать Ctrl + Alt + Del, при появлении меню "Завершение работы программы" ввод разблокируется.

А вот еще интересный прикол.
Включение/выключение монитора программным способом.

Предупреждаю сразу! После того, как вы отключите монитор, просто так вы его уже не включите (хотя это может быть зависит от монитора, я, во всяком случае, не смог). Только после перезагрузки компьютера.

Отключить :
SendMessage(Application.Handle, WM_SYSCOMMAND, SC_MONITORPOWER, 0);

Включить :
SendMessage(Application.Handle, WM_SYSCOMMAND, SC_MONITORPOWER, -1);

Источник: 



Внести изменения в набор данных и не потерять текушей позиции


Внести изменения в набор данных и не потерять текушей позиции




procedureTMyForm.MakeChanges;
var
  aBookmark: TBookmark;
begin
  Table1.DisableControls;
  aBookmark := Table.GetBookmark;
  try
    {ваш код}
  finally
    Table1.GotoBookmark(aBookmark);
    Table1.FreeBookmark(aBookmark);
    Table1.EnableControls;
  end;
end

Взято из





Вопросы инсталяции програм


Вопросы инсталяции програм



Cодержание раздела:







См. также статьи в других разделах:




См. также другие разделы:





Вопросы локализации програм


Вопросы локализации програм



Cодержание раздела:






Вопросы оптимизации и отладки програм


Вопросы оптимизации и отладки програм



Cодержание раздела:












См. также статьи в других разделах:














Вопросы защиты и взлома програм


Вопросы защиты и взлома програм



Cодержание раздела:










См. также статьи в других разделах:






См. также другие разделы:






Восстановление минимизированного приложения


Восстановление минимизированного приложения



При минимизации формы я использую RxTrayIcon, чтобы при этом исчезла
кнопка из Панели задач вызываю ShowWindow(Application.Handle,SW_HIDE).
Но вот незадача - не получается при восстановлении приложения (после клика
на TrayIcon) добиться, чтобы оно становилось поверх других окон и обязательно было активным.

Дело оказалось в следующем : гасить Tray-иконку надо в последнюю очередь,
именно так все работает(ранее сначала гасил Tray-иконку, а уже потом восттанавливал свое приложение).
Таким образом правильно работает следующий код:

procedure TForm1.ApplicationMinimize(Sender : TObject);
begin
 RxTrayIcon1.Show;
 ShowWindow(Application.Handle,SW_HIDE);
end;

procedure TForm1.RxTrayIcon1Click(Sender: TObject; Button: TMouseButton;
         Shift: TShiftState; X, Y: Integer);
begin
 Application.Restore;
 SetForeGroundWindow(Application.MainForm.Handle);
 RxTrayIcon1.Hide;
end;

Авторы ответа: Song, Den
Взято с Vingrad.ru




Восстановление записи dBase


Восстановление записи dBase




functionGetTableCursor(oTable: TTable): hDBICur;
var
  szTable: array[0..78] of Char;
begin
  StrPCopy(szTable, oTable.TableName);
  DbiGetCursorForTable(oTable.DBHandle, szTable, nil, Result);
end;

function dbRecall(oTable: TTable): DBIResult;
begin
  Result := DbiUndeleteRecord(GetTableCursor(oTable)));
end;

Предположим, у вас на форме имеется кнопка (с именем 'butRecall'), восстанавливающая текущую отображаемую (или позиционируемую курсором) запись, данный код, будучи расположенный в обработчике события кнопки OnClick (вместе с опубликованным выше кодом), это демонстрирует (продвигаясь в наших предположених дальше, имя вашего объекта TTable - Table1 и имя текущей формы - Form1):

procedure TForm1.butRecallClick(Sender: TObject);
begin
  if dbRecall(Table1) <> DBIERR_NONE then
    ShowMessage('Не могу восстановить запись!');
end;

- Loren Scott

Взято из

Советов по Delphi от


Сборник Kuliba






Возникает сложность копирования MS Access


Возникает сложность копирования MS Access



Говорит мол невозможно открыть файл. И на самом деле еще виден файл блокировки Access. Как закрыть базу так чтоб этот файл исчез и я мог сохранить.

Ответ:

session.close

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




Вращение объектов


Вращение объектов




Здесь я бы хотел рассказать не о том, как работать с DelphiX, OpenGL или Direct, а о том, как можно вращать многогранники с помощью простых действий: moveto и lineto.

Здесь рассмотрим пример вращения куба. Будем рисовать на Canvase (например Listbox). Сначала нарисуем врашающийся квадрат (точнее 2 квадрата и соединим их). Пусть q - угол поворота квадрата, который мы рисуем. Очевидно, что нам надо задать координаты вершин квадрата - a:array [1..5,1..2] of integer. 1..4+1 - количество вершин квадрата (почему +1 будет объяснено позже). 1..2 - координата по X и Y. Кто учился в школе, наверное помнит, что уравнение окружности: X^2+Y^2=R^2, кто хорошо учился в школе, возможно вспомнит уравнение эллипса: (X^2)/(a^2)+ (Y^2)/(b^2)=1. Но это нам не надо. Нам понадобится уравнение эллипса в полярных координатах: x=a*sin(t); y=a*cos(t);t=0..2*PI; (учащиеся университетов и институтов ликуют).

С помощью данного уравнения мы заполняем массив с координатами.

fori:=1 to 5 do
begin
  // координата по Х; q+i*pi/2 - угол поворота
  // i-той вершины квадрата.
  a[i,1]:=trunc(80*sin(q+i*pi/2));
  // координата по Y; знак минус - потому что координаты
  // считаются с верхнего левого угла
  a[i,1]:=trunc(-30*cos(q+i*pi/2));
end;

Сейчас будем рисовать квадрат:

for i:=1 to 4 do
begin
  moveto(100+a[i,1],50+a[i,2]); //Встаем на i-ую точку квадрата.
  lineto(100+a[i+1,1],50+a[i+1,2]); //Рисуем линию к i+1-ой точке.

Вот почему array[1..5,1..2], иначе - выход за границы. end;

Затем рисуем второй такой же квадрат, но пониже (или повыше). Соединяем линиями первый со вторым:

for i:=1 to 4 do
begin
  moveto(100+a[i,1],50+a[i,2]);
  lineto(100+a[i,1],130+a[i,2]);
end;

Осталось очистить Listbox, увеличить q и сделать сначала. Все!!!

Можно также скрывать невидимые линии - когда q находится в определенном интервале. Также можно поизвращаться: повернуть куб в другой плоскости - поворот осей(для тех, кто знает формулу).


Автор: Айткулов Павел
WEB-сайт: http://rax.ru/click?apg67108864.narod.ru/

Взято из





Всё о файлах (Статья)


Всё о файлах (Статья)



Решил здесь собрать воедино основные приемы работы с файлами.

Автор

Vit
Взято с Vingrad.ru




Вскрытие запароленной таблицы Paradox


Вскрытие запароленной таблицы Paradox




Предупрежден - значит, вооружен. Берем Парадоксовскую табличку, паролим ее самым секретным паролем, бумажку с паролем сжигаем, а сам пароль забываем. Что теперь делать? Да ничего, просто открываем нашу табличку с одним из паролей: jIGGAe, nx66ppx, cupcdvum. Один, да подойдет.

Взято из

Советов по Delphi от


Сборник Kuliba






Вставка одних компонентов в другие


Вставка одних компонентов в другие



Cодержание раздела:











См. также статьи в других разделах:





Встроенные форматы буфера обмена


Встроенные форматы буфера обмена




Автор: Peter Below



procedureTForm1.BtnShowFormatsClick(Sender: TObject);
var
  buf: array[0..60] of Char;
  n: Integer;
  fmt: Word;
  name: string[30];
begin
  MemFormats.Clear;
  for n := 0 to Clipboard.FormatCount - 1 do
  begin
    fmt := Clipboard.Formats[n];
    if GetclipboardFormatName(fmt, buf, Pred(Sizeof(buf))) <> 0 then
      MemFormats.Lines.Add(StrPas(buf))
    else
    begin
      case fmt of
        1: name := 'CF_TEXT';
        2: name := 'CF_BITMAP';
        3: name := 'CF_METAFILEPICT';
        4: name := 'CF_SYLK';
        5: name := 'CF_DIF';
        6: name := 'CF_TIFF';
        7: name := 'CF_OEMTEXT';
        8: name := 'CF_DIB';
        9: name := 'CF_PALETTE';
        10: name := 'CF_PENDATA';
        11: name := 'CF_RIFF';
        12: name := 'CF_WAVE';
        13: name := 'CF_UNICODETEXT';
        14: name := 'CF_ENHMETAFILE';
        15: name := 'CF_HDROP (Win 95)';
        16: name := 'CF_LOCALE (Win 95)';
        17: name := 'CF_MAX (Win 95)';
        $0080: name := 'CF_OWNERDISPLAY';
        $0081: name := 'CF_DSPTEXT';
        $0082: name := 'CF_DSPBITMAP';
        $0083: name := 'CF_DSPMETAFILEPICT';
        $008E: name := 'CF_DSPENHMETAFILE';
        $0200..$02FF: name := 'частный формат';
        $0300..$03FF: name := 'Объект GDI';
      else
        name := 'неизвестный формат';
      end;
      MemFormats.Lines.Add(name);
    end;
  end;
end;





Взято с






COM при программировании на Delphi

Автор Бин Ли

Я всегда твердо верил, что нет ничего такого, что было бы невозможно понять. Необходимо только "выпарить" наиболее сложные части проблемы и потратить какое-то количество времени на понимание частей проблемы "кусок за куском". Затем эти части собрать вместе и понять проблему целиком.

Потоковые модели в COM имеют репутацию наиболее сложных для понимания. Возможно потому, что множество имеющейся документации по этой теме имеет "техническую природу" или ориентировано на конкретный язык, чаще всего C или C++. Цель этой статьи - дать Вам возможность понять, почему потоковые модели в COM так важны и как правильно использовать потоковые модели в Ваших приложениях COM. Моя цель - представить Вам материал таким образом, чтобы Вы могли читать его последовательно от начала до конца и в результате понять всю статью. Сказав это, я бы настойчиво рекомендовал Вам не пропускать ни одной страницы в процессе чтения, чтобы у Вас не возникло трудностей оттого, что Вы что-то пропустили раньше. А теперь, я желаю Вам удачи, и не говорите, что я не предупреждал Вас об этом!
Прежде, чем начать изложение, давайте начнем с того, что поймем, почему потоковые модели так важны для Ваших приложений COM. Исходя из своего опыта, я могу сказать, что наиболее существенной причиной использования потоковых моделей является повышение общей производительности и скорости реакции Вашей программы, особенно для объектов серверов COM, которые используются для обслуживания большого количества клиентских приложений. Но я не хочу сказать, что использование потоковых моделей в Ваших объектах серверов COM всегда увеличивает производительность. Вы должны тщательно изучить, как используются Ваши объекты и как потоковая модель повлияет на производительность приложения и целостность данных. Я должен подчеркнуть, что вопросы целостности обязательно должны рассматриваться объектов при принятии решения, применять или нет потоковую модель.
Несмотря на то, что Вы можете думать, что использование потоковой модели существенно повысит производительность объекта, может оказаться, что Ваши объекты сильно зависят, скажем, от третьих библиотек, которые могут "не выжить" в условиях многопоточности. Другой хорошей причиной применения многопоточности может быть то, что задача по своей природе является весьма пригодной для многопоточной реализации. Например, серверные объекты, являющиеся чисто служебными объектами, вероятно, могут сильно зависеть от времени при выполнении операций или захватывании ресурсов. Примерами таких объектов являются мониторы работы оборудования, объекты пакетной обработки или даже простые объекты манипулирования данными, время исполнения которых для успешного завершения непредсказуемо. В этих случаях тип разрабатываемого Вами приложения по существу определяет использование многопоточности.
Имеется множество других причин, при которых Вы могли бы использовать многопоточность, но две упомянутые выше причины являются наиболее общими среди наблюдаемых в промышленном программировании.
С другой стороны, я бы хотел предупредить, что не стоит применять многопоточность, если Вы не нуждаетесь в ней или не можете понять преимущества получаемого при этом решения. Это означает, что Вам не стоит даже думать о многопоточности, если Вы думаете только о том, что это круто. Поверьте мне, использование мнопоточности существенно усложняет Ваше приложение и, если Вы недостаточно все продумали, Вам придется искать ошибки в тех местах программы, которые прекрасно работали в однопоточном исполнении.

Ввести пароль Paradox


Ввести пароль Paradox




Как мне при соединении с таблицей Paradox устранить/"удовлетворить" окошко с требованием ввести пароль, защищающей таблицу?

Свойство компонента Table ACTIVE должно быть установлено в FALSE. (Если она активна прежде, чем вы ввели пароль, вы получите это окошко.) Затем поместите следующий код в обработчике события формы OnCreate:

session.AddPassword('Мойсекретный пароль');
table1.active := true;  

Взято из

Советов по Delphi от


Сборник Kuliba






Вычисление интеграла


Вычисление интеграла




Вычисление интеграла с заданной точностью алгоритмом Симпсона.



//(c) Copydown 2002, all left reserved. http://world.fpm.kubsu.ru.

{$APPTYPE CONSOLE}

{$F+} {разрешение передачи функций, как параметров}

type FunctionType = function(x: real): real;

{интегрируемая функция}
function f(x: real): real; begin f := x end;

{интегрирование от a до b функции f с точностью e}
function IntegralSimpson(a, b: real; f: FunctionType; e: real): real;
  var
    h, x, s, s1, s2, s3, sign: real;
 begin

  if (a = b) then
    begin
      IntegralSimpson := 0; exit
    end;

  if (a > b) then
    begin
      x := a; a := b; b := x; sign := -1
    end
   else sign:=1;

  h := b - a; s := f(a) + f(b); s2 := s;

  repeat
    s3 := s2; h := h/2; s1 := 0; x := a + h;

    repeat
      s1 := s1 + 2*f(x); x := x + 2*h;
    until (not(x < b));

    s := s + s1; s2 := (s + s1)*h/3; x := abs(s3 - s2)/15
  until (not(x > e));

  IntegralSimpson := s2*sign;
 end;

begin
  {вывод результата интегрирования от 0 до 1 функции f с точностью 0.001}
  writeln(IntegralSimpson(0, 1, f, 0.001));
  writeln; writeln('Press Enter'); readln;
end.


 

Взято с






Выключение питания ATX коpпуса из-под DOS


Выключение питания ATX коpпуса из-под DOS




movax,5301h
        sub bx,bx
        int 15h
        jb stop
        mov ax,530eh
        sub bx,bx
        int 15h
        jb stop
        mov ax,5307h
        mov bx,0001h
        mov cx,0003h
        int 15h
  stop: int 20h

Код прислал Колесников Сергей Александрович [mailto:rovd@inbox.ru]

Взято из

Советов по Delphi от


Сборник Kuliba






Выполнение процедуры по адресу


Выполнение процедуры по адресу





varF: procedure(x, y: double);

  @F := GetProcAddress(hDLL, 'SOMEPROC');
  F(3, 4);

Ключом здесь является использование оператора @, располагаемого с левой части процедурной переменной. Он говорит компилятору: "Не волнуйтесь здесь о совместимости типов, просто присвойте полученный в правой части выражения адрес переменной в левой части выражения (и процедурные переменные являются переменными-указателями).

- Peter Below

Взято из

Советов по Delphi от


Сборник Kuliba






Выполнение запросов к базе данных в фоне


Выполнение запросов к базе данных в фоне




Данный документ объясняет как выполнить запрос в фоновом режиме, используя класс TThread. Для получения общей информации о классе TThread, пожалуйста обратитесь к документации Borland и электронной справке. Для понимания данного документа вам необходимо иметь представление о том, как работать с компонентами для работы с базами данных, поставляемых в комплекте с Delphi 2.0.

Для осуществления потокового запроса необходимо выполнение двух требований. Во-первых, потоковый запрос должен находиться в своей собственной сессии с использованием отдельного компонента TSession. Следовательно, на вашей форме должен находиться компонент TSession, имя которого должно быть назначено свойству SessonName компонента TQuery, используемого для выполнения потокового запроса. Для каждого используемого в потоке компонента TQuery вы должны использовать отдельный компонент TSession. При использовании компонента TDataBase, для отдельного потокового запроса должен также использоваться отдельный TDataBase. Второе требование заключается в том, что компонент TQuery, используемый в потоке, не должен подключаться в контексте это потока к TDataSource. Это должно быть сделано в контексте первичного потока.

Приведенный ниже пример кода иллюстрирует описываемый процесс. Данный модуль демонстрирует форму, которая содержит по два экземпляра следующих компонентов: TSession, TDatabase, TQuery, TDataSource и TDBGrid. Данные компоненты имеют следующие значения свойств:

Session1 
   Active   True;
   SessionName   "Ses1"

  DataBase1
   AliasName   "IBLOCAL"
   DatabaseName   "DB1"
   SessionName   "Ses1"

  Query1
   DataBaseName   "DB1"
   SessionName   "Ses1"
   SQL.Strings   "Select * from employee"

  DataSource1
   DataSet   ""

  DBGrid1
   DataSource   DataSource1

  Session2
   Active   True;
   SessionName   "Ses2"

  DataBase2
   AliasName   "IBLOCAL"
   DatabaseName   "DB2"
   SessionName   "Ses2"

  Query2
   DataBaseName   "DB2"
   SessionName   "Ses2"
   SQL.Strings   "Select * from customer"

  DataSource2
   DataSet   ""

  DBGrid1
   DataSource   DataSource2

Обратите внимание на то, что свойство DataSet обоих компонентов TDataSource первоначально никуда не ссылается. Оно устанавливается во время выполнения приложения, и это проиллюстрировано в коде.



unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls,
  Forms, Dialogs, StdCtrls, Grids, DBGrids, DB, DBTables;

type

  TForm1 = class(TForm)
    Session1: TSession;
    Session2: TSession;
    Database1: TDatabase;
    Database2: TDatabase;
    Query1: TQuery;
    Query2: TQuery;
    DataSource1: TDataSource;
    DataSource2: TDataSource;
    DBGrid1: TDBGrid;
    DBGrid2: TDBGrid;
    GoBtn1: TButton;
    procedure GoBtn1Click(Sender: TObject);
  end;

  TQueryThread = class(TThread)
  private
    FSession: TSession;
    FDatabase: TDataBase;
    FQuery: TQuery;
    FDatasource: TDatasource;
    FQueryException: Exception;
    procedure ConnectDataSource;
    procedure ShowQryError;
  protected
    procedure Execute; override;
  public
    constructor Create(Session: TSession; DataBase:
      TDatabase; Query: TQuery; DataSource: TDataSource);
      virtual;
  end;

var
  Form1: TForm1;

implementation

constructor TQueryThread.Create(Session: TSession; DataBase: TDatabase; Query:
  TQuery; Datasource: TDataSource);
begin
  inherited Create(True); // Создаем поток c состоянием suspendend
  FSession := Session; // подключаем все privat-поля
  FDatabase := DataBase;
  FQuery := Query;
  FDataSource := Datasource;
  FreeOnTerminate := True;
    // Устанавливаем флаг освобождения потока после его завершения
  Resume; // Продолжение выполнения потока
end;

procedure TQueryThread.Execute;
begin
  try
    { Выполняем запрос и подключаем источник данных к компоненту TQuery,
    вызывая ConnectDataSource из основного потока
    (для этой цели используем Synchronize)}
    FQuery.Open;
    Synchronize(ConnectDataSource);
  except
    { Ловим исключение (если оно происходит) и его дескриптор
    в контексте основного потока (для этой цели используем
    Synchronize). }
    FQueryException := ExceptObject as Exception;
    Synchronize(ShowQryError);
  end;
end;

procedure TQueryThread.ConnectDataSource;
begin
  FDataSource.DataSet := FQuery; // Подключаем DataSource к TQuery
end;

procedure TQueryThread.ShowQryError;
begin
  Application.ShowException(FQueryException); // Обрабатываем исключение
end;

procedure RunBackgroundQuery(Session: TSession; DataBase: TDataBase; Query:
  TQuery; DataSource: TDataSource);
begin
  { Создаем экземпляр TThread с различными параметрами. }
  TQueryThread.Create(Session, Database, Query, DataSource);
end;

{$R *.DFM}

procedure TForm1.GoBtn1Click(Sender: TObject);
begin
  { Запускаем два отдельных запроса, каждый в своем потоке }
  RunBackgroundQuery(Session1, DataBase1, Query1, Datasource1);
  RunBackgroundQuery(Session2, DataBase2, Query2, Datasource2);
end;

end.


Метод TForm1.GoBtn1Click является обработчиком события нажатия кнопки. Данный обработчик события дважды вызывает процедуру RunBackgroundQuery, это случается при каждой передаче новых параметров компонентам для работы с базой данных. RunBackgroundQuery создает отдельный экземпляр класса TQueryThread, передает различные компоненты для работы с базой данных в его конструктор, который, в свою очередь, назначает их закрытым полям TQueryThread.

TQueryThread содержит две определенные пользователем процедуры: ConnectDataSource и ShowQryError. ConnectDataSource связывает FDataSource.DataSet с FQuery. Тем не менее, это делается в первичном потоке с помощью метода TThread.Synchronize. ShowQryError обрабатывает исключение в контексте первиного потока, также используя метод Synchronize. Конструктор Create и метод Execute снабжены подробными комментариями.

Взято из





Выполняем встроенные команды Windows


Выполняем встроенные команды Windows



Автор:

Ruslan Abu Zant
Компилятор: Delphi 4.x (или выше)

Впринципе эти команды можно запускать в меню "Выполнить..." (Run), кнопки Пуск. Ну а в Delphi они запускаются путём всем извесной команды winexec(Pchar('ABCD'),sw_Show);
где 'ABCD' - одна из следующих команд ...

"rundll32 shell32,Control_RunDLL" - Запустить Панель Управления

"rundll32 shell32,OpenAs_RunDLL" - Открыть диалог "Открыть Как ..." ('Open With...')

"rundll32 shell32,ShellAboutA Info-Box" - Открыть 'About Window Window'

"rundll32 shell32,Control_RunDLL desk.cpl" - Открыть диалог "Свойства: Экран" (Display Properties)

"rundll32 user,cascadechildwindows" - Выстроить все окна каскадно

"rundll32 user,tilechildwindows" - Свернуть все окна

"rundll32 user,repaintscreen" - Обновить Десктоп

"rundll32 shell,shellexecute Explorer" - Перезапустить Проводник

"rundll32 keyboard,disable" - Заблокировать Клавиатуру

"rundll32 mouse,disable" - Запретить мышку

"rundll32 user,swapmousebutton" - Поменять кнопки мыши

"rundll32 user,setcursorpos" - Установить Курсор в позицию (0,0)

"rundll32 user,wnetconnectdialog" - Показать диалог "Подключить сетевой диск" ('Map Network Drive')

"rundll32 user,wnetdisconnectdialog" - Показать диалог "Отключить сетевой диск" ('Disconnect Network Disk')

"rundll32 user,disableoemlayer" - Отобразить окно BSOD ('''(BSOD) = Blue Screen Of Death ''')

"rundll32 diskcopy,DiskCopyRunDll" - Показать диалог копирования диска

"rundll32 rnaui.dll,RnaWizard" - Запустить 'Internet Connection Wizard'
"rundll32 shell32,SHFormatDrive" - Запустить окно форматирования дискеты ('Format Disk (A)')

"rundll32 shell32,SHExitWindowsEx -1" - "Холодный" перезапуск Проводника

"rundll32 shell32,SHExitWindowsEx 1" - Выключить компьютер

"rundll32 shell32,SHExitWindowsEx 0" - Завершить сеанс текущего пользователя

"rundll32 shell32,SHExitWindowsEx 2" Быстрый перезапуск Windows9x

"rundll32 krnl386.exe,exitkernel" - Выход из Windows 9x без потверждения

"rundll rnaui.dll,RnaDial "MyConnect" - Запустить диалог 'Net Connection'

"rundll32 msprint2.dll,RUNDLL_PrintTestPage" - Выбор и печать тестовой страницы текущего принтера

"rundll32 user,setcaretblinktime" - Усатновить скорость мигания курсора

"rundll32 user, setdoubleclicktime" - Установить скорость двойного нажатия

"rundll32 sysdm.cpl,InstallDevice_Rundll" - Поиск устройств не PnP.

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