nyuuzyou/wikis huggingface dataset:
Index not found Exception

=== Index not found Exception ===
{Q: How do I open a dBASE table without the required MDX file?
 I keep getting an "Index not found..." exception.}
{A: When you create a dBASE table with a production index (MDX), a
 special byte is set in the header of the DBF file. When you
 subsequently attempt to re-open the table, the dBASE driver
 will read that special byte, and if it is set, it will also
 attempt to open the MDX file. When the MDX file cannot be
 opened, an exception is raised.
 To work around this problem, you need to reset the byte (byte
 28 decimal) in the DBF file that causes the MDX dependency
 to zero.
 The following unit is a simple example of how to handle the
 exeption on the table open, reset the byte in the DBF file,
 and re-open the table.}
unit Fixit;
interface
uses
 SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics,
 Controls, Forms, Dialogs, StdCtrls, DB, DBTables, Grids, DBGrids;
type
 TForm1 = class(TForm)
 Table1: TTable;
 Button1: TButton;
 procedure Button1Click(Sender: TObject);
 private
 { Private declarations }
 public
 { Public declarations }
 end;
var
 Form1: TForm1;
implementation
{$R *.DFM}
const
 TheTableDir = 'c:\temp\';
 TheTableName = 'animals.dbf';
procedure RemoveMDXByte(dbFile: string);
 { This procedure accepts a DBF file as a parameter. It will patch}
 { the DBF header, so that it no longer requires the MDX file }
const
 Value: Byte = 0;
var
 F: file of byte;
begin
 AssignFile(F, dbFile);
 Reset(F);
 Seek(F, 28);
 Write(F, Value);
 CloseFile(F);
end;
procedure TForm1.Button1Click(Sender: TObject);
 { This procedure is called in response to a button click. It }
 { attempts to open a table, and, if it can't find the .MDX file, }
 { it patches the DBF file and re-execute the procedure to }
 { re-open the table without the MDX }
begin
 try
 { set the directory for the table }
 Table1.DatabaseName := ThheTableDir;
 { set the table name }
 Table1.TableName := TheTableName;
 { attempt to open the table }
 Table1.Open;
 except
 on E: EDBEngineError do
 { The following message indicates the MDX wasn't found: }
 if Pos('Index does not exist. File', E.Message) > 0 then
 begin
 { Tell user what's going on. }
 MessageDlg('MDX file not found.Attempting to Open
 without Index.', mtWarning, [mbOK], 0);
 { remove the MDX byte from the table header }
 RemoveMDXByte(TheTableDir + TheTableName);
 { Send the button a message to make it think it was }
 { pressed again. Doing so will cause this procedure to }
 { execute again, and the table will be opened without }
 { the MDX }
 PostMessage(Button1.Handle, cn_Command, bn_Clicked, 0);
 end;
 end;
end;
end.
Source: Взято с сайта http://www.swissdelphicenter.ch/en/tipsindex.php
ID: 02708
InputBox для ввода пароля

const
 InputBoxMessage = WM_USER + 200;
type
 TForm1 = class(TForm)
 Button1: TButton;
 procedure Button1Click(Sender: TObject);
 private
 procedure InputBoxSetPasswordChar(var Msg: TMessage); message InputBoxMessage;
 public
 end;
var
 Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.InputBoxSetPasswordChar(var Msg: TMessage);
var
 hInputForm, hEdit, hButton: HWND;
begin
 hInputForm := Screen.Forms[0].Handle;
 if (hInputForm <> 0) then
 begin
 hEdit := FindWindowEx(hInputForm, 0, 'TEdit', nil);
 {
 // Change button text:
 hButton := FindWindowEx(hInputForm, 0, 'TButton', nil);
 SendMessage(hButton, WM_SETTEXT, 0, Integer(PChar('Cancel')));
 }
 SendMessage(hEdit, EM_SETPASSWORDCHAR, Ord('*'), 0);
 end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
 InputString: string;
begin
 PostMessage(Handle, InputBoxMessage, 0, 0);
 InputString := InputBox('Input Box', 'Please Enter a Password', );
end;
Source: Взято с сайта: http://www.swissdelphicenter.ch
ID: 04031
Category:WinAPI
Category:Безопасность
Integer как SmallInt

=== Integer как SmallInt ===
Я перешел на Delphi 2.0 и у меня появилась проблема с типизированными файлами. У меня есть множество типизированных файлов с различными записями. Теперь, когда целое занимает 4 байта, определения всех моих записей должны быть изменены с расчетом на то, что вместо целого типа придется использовать тип SmallInts. Тем не менее, даже после такого изменения размер моих записей остается прежним... 
Вам необходимо использовать модификатор "packed": 
type
 TMyRecType = packed record
 //...
 end;
Author: Steve Schafer
Source: Взято с http://delphiworld.narod.ru
ID: 00222
Integer → BIN

=== Integer --> BIN ===
function IntToBin1(Value: Longint; Digits: Integer): string;
var
 i: Integer;
begin
 Result := ;
 for i := Digits downto 0 do
 if Value and (1 shl i) <> 0 then
 Result := Result + '1'
 else
 Result := Result + '0';
end;
Source: Взято с сайта: http://www.swissdelphicenter.ch
ID: 00940
----
function IntToBin2(d: Longint): string;
var
 x, p: Integer;
 bin: string;
begin
 bin := ;
 for x := 1 to 8 * SizeOf(d) do
 begin
 if Odd(d) then 
 bin := '1' + bin
 else
 bin := '0' + bin;
 d := d shr 1;
 end;
 Delete(bin, 1, 8 * ((Pos('1', bin) - 1) div 8));
 Result := bin;
end;
Source: Взято с сайта: http://www.swissdelphicenter.ch
ID: 00941
JPG в BMP

jpeg.CompressionQuality - качество сжатия (по умолчанию 100)
Установите значение 1..100, в зависимости от желаемого качества и размера файла картинки. 1 = минимальный размер, 100 = лучшее качество.
uses
 JPEG;
procedure JPEGtoBMP(const FileName: TFileName);
var
 jpeg: TJPEGImage;
 bmp: TBitmap;
begin
 jpeg := TJPEGImage.Create;
 try
 jpeg.CompressionQuality := 100; { Default Value }
 jpeg.LoadFromFile(FileName);
 bmp := TBitmap.Create;
 try
 bmp.Assign(jpeg);
 bmp.SaveTofile(ChangeFileExt(FileName, '.bmp'));
 finally
 bmp.Free
 end;
 finally
 jpeg.Free
 end;
end;
Source: http://www.swissdelphicenter.ch/en/tipsindex.php
ID: 04279
== См. также ==
* BMP в JPG
Category:Конвертация
Libqt для Kylix с поддержкой сглаживания

Люди, просьба, проверьте работает ли на ваших дистрибутивах сие чудо перед запуском программы на Kylix напишите в командной строке
 export CLX_USE_LIBQT="True"
 export QT_XFT="1"
скопируйте эти библиотеки в /usr/lib и попробуйте запустить потом свою прогу из этой же консоли, чтоб переменные окружения не пропали! Надеюсь заработает
http://cracker-shym.narod.ru/program/Kylix/libqt.zip
У меня на 10 SlackWare заработало
Добавил еще откомпилированную версию libqt версии 2.3.2, последнюю из QT2, вроде также работает на СлакВаре 10, попутно велез баг, известный у QT2 давно, не видит шрифты некоторые при включенном сглаживании шрифтов, так что некоторые надписи могут не показыватся пока не сменишь шрифт, а так вроде работает!
Author: haword 
Source: Vingrad.ru http://forum.vingrad.ru
ID: 04594
Category:Kylix
Category:Linux
Category:Qt
Local SQL и временная таблица

=== Local SQL и временная таблица ===
Local SQL не поддерживает вложенные запросы, но после того как я заработал клок седых волос, я нашел в высшей степени простое решение: использование временной таблицы.
Пример:
with GeneralQuery do
begin
 SQL.Clear;
 SQL.Add({.... внутренний SQL});
 SQL.Open;
 DbiMakePermanent(handle, 'temp.db', True);
 SQL.Clear;
 SQL.Add('SELECT ... FROM "temp.db" ....');
 SQL.Open;
end;
Единственное: необходимо убедиться в том, что имя таблицы не вступает в конфликт с именами нескольких работающих копий таблицы. И, разумеется, данная технология не даст "живой" набор!
Source: Взято с http://delphiworld.narod.ru
ID: 02606
MS Binder

== Opening Binder (early binding) ==
Before you can use this method, you must have imported the type library (MSBdr8.olb for Binder 97).
One way of starting Binder is to try the GetActiveObject call, to get a running instance of Binder, but put a call to CoApplication.Create in an except clause. But except clauses are slow, and can cause problems within the IDE for people who like Break On Exceptions set to True. The following code removes the need for a try...except clause, by avoiding using OleCheck on GetActiveObject in the case when Binder is not running.
uses Windows, ComObj, ActiveX, OfficeBinder_TLB;
var
 Binder: _Binder;
 AppWasRunning: Boolean; // tells you if you can close Binder when you've finished
 Unknown: IUnknown;
 Result: HResult;
begin
 AppWasRunning := False;
 Result := GetActiveObject(CLASS_Binder, nil, Unknown);
 if (Result = MK_E_UNAVAILABLE) then
 Binder := CoBinder.Create
 else
 begin
 { make sure no other error occurred during GetActiveObject }
 OleCheck(Result);
 OleCheck(Unknown.QueryInterface(_Binder, Binder));
 AppWasRunning := True;
 end;
 Binder.Visible := True;
 {...}
== Without using the type library ==
Automation is so much easier and faster using type libraries (early binding) that you should avoid managing without if at all possible. But if you really can't, here's how to get started:
var
 Binder: Variant;
begin
 try
 Binder := GetActiveOleObject('Office.Binder');
 except
 Binder := CreateOleObject('Office.Binder');
 end;
 Binder.Visible := True;
== How to close Binder ==
Here's the quick version:
Binder.Close(False, );
The first parameter determines whether changes to the open binder will be saved before closing. If you use EmptyParam for this parameter, the user will be asked whether to save if appropriate.
The second parameter is for the name the binder should be given when it is saved, if it hasn't already been given a name. If the binder has already been saved, this parameter is ignored.
ID: 04472
Category:COM
Category:MS Office
Memo too large

=== Memo too large ===
В BDE есть крутая ошибка, достаточно известная всем, кроме Borland'a. Поскольку они ее еще с 1-й Delphi не исправили. Этот баг проявляется как Access Violation в программе при обращении к таблице IB, которая содержит более одного поля типа VARCHAR (или CHAR) размером > 255. Причем, первое поле меньшего, а второе большего размера. Если поменять местами поля или сделать их одного размера, то все нормально.
Эффект имеет место только с IB, вроде.
Source: Взято с http://delphiworld.narod.ru
ID: 02583
Memo со свойствами Row и Col

=== Memo со свойствами Row и Col ===
Наследник TMemo со свойствами row, col:
unit C_rcmemo;
interface
uses
 SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
 Forms, Dialogs, StdCtrls;
type
 TRCMemo = class(TMemo)
 private
 { Private declarations }
 function GetRow: Integer;
 procedure SetRow(value: Integer);
 function GetCol: Integer;
 procedure SetCol(value: Integer);
 function GetPosn: LongInt;
 procedure SetPosn(value: LongInt);
 protected
 { Protected declarations }
 public
 { Public declarations }
 published
 { Published declarations }
 property Row: Integer read GetRow write SetRow;
 property Col: Integer read GetCol write SetCol;
 property Posn: LongInt read GetPosn write SetPosn;
 end;
procedure Register;
implementation
function TRCMemo.GetRow: Integer;
begin
 Result := Perform(EM_LINEFROMCHAR, $FFFF, 0);
end;
procedure TRCMemo.SetRow(value: Integer);
begin
 SelStart := GetCol + Perform(EM_LINEINDEX, Value, 0);
end;
function TRCMemo.GetCol: Integer;
begin
 Result := SelStart - Perform(EM_LINEINDEX, GetRow, 0);
end;
procedure TRCMemo.SetCol(value: Integer);
begin
 SelStart := Perform(EM_LINEINDEX, GetRow, 0) + Value;
end;
function TRCMemo.GetPosn: LongInt;
var
 ro, co: Integer;
begin
 ro := GetRow;
 co := SelStart - Perform(EM_LINEINDEX, ro, 0);
 Result := MakeLong(co, ro);
end;
procedure TRCMemo.SetPosn(value: LongInt);
begin
 SelStart := Perform(EM_LINEINDEX, HiWord(Value), 0) + LoWord(Value);
end;
procedure Register;
begin
 RegisterComponents('NJR', [TRCMemo]);
end;
end.
Source: http://delphiworld.narod.ru/
ID: 00987
Method pointers в function pointers

=== Method pointers --> function pointers ===
{
 Converting method pointers into function pointers
 Often you need a function pointer for a callback function. But what, 
 if you want to specify a method as an callback? Converting a method 
 pointer to a function pointer is not a trivial task; both types are
 incomatible with each other. Although you have the possibility to 
 convert like this "@TClass.SomeMethod", this is more a hack than a 
 solution, because it restricts the use of this method to some kind 
 of a class function, where you cannot access instance variables. 
 If you fail to do so, you'll get a wonderful gpf. But there is 
 a better solution: run time code generation! Just allocate an 
 executeable memory block, and write 4 machine code instructions into 
 it: 2 instructions loads the two pointers of the method pointer
 (code & data) into the registers, one calls the method via the code 
 pointer, and the last is just a return Now you can use this pointer 
 to the allocated memory as a plain funtion pointer, but in fact you are
 calling a method for a specific instance of a Class.
}
type TMyMethod = procedure of object;
function MakeProcInstance(M: TMethod): Pointer;
begin
 // allocate memory
 GetMem(Result, 15);
 asm
 // MOV ECX, 
 MOV BYTE PTR [EAX], $B9
 MOV ECX, M.Data
 MOV DWORD PTR [EAX+$1], ECX
 // POP EDX
 MOV BYTE PTR [EAX+$5], $5A
 // PUSH ECX
 MOV BYTE PTR [EAX+$6], $51
 // PUSH EDX
 MOV BYTE PTR [EAX+$7], $52
 // MOV ECX, 
 MOV BYTE PTR [EAX+$8], $B9
 MOV ECX, M.Code
 MOV DWORD PTR [EAX+$9], ECX
 // JMP ECX
 MOV BYTE PTR [EAX+$D], $FF
 MOV BYTE PTR [EAX+$E], $E1
 end;
end;
procedure FreeProcInstance(ProcInstance: Pointer);
begin
 // free memory
 FreeMem(ProcInstance, 15);
end;
{
 After all, you should not forget to release the allocated memory.
 "TMyMethod" can be modified according your specific needs, e.g. 
 add some parameters for a WindowProc. N.B.: Yes, I know, Delphi 
 has those "MakeProcInstance" function in its forms unit. But this 
 works a little bit different, has much more overhead, and most 
 important, you have to use the forms unit, which increases the 
 size of your exe drastically, if all other code doesn't use the 
 VCL (e.g. in a fullscreen DirectX/OpenGl app).
// Wer noch Fragen hat / if you have questions: Florian.Benz@t-online.de
}
Language: en
Source: Взято с сайта http://www.swissdelphicenter.ch/en/tipsindex.php
ID: 00259
Multiple records found, but only one was expected

=== Multiple records found, but only one was expected ===
При выполнении некоторых живых запросов, возвращающих единственную запись, BDE ругается 'multiple records found, but only one was expected'.
Запросы вида
SELECT c, b, a, q FROM T WHERE b = :b
где ключ c, но BDE посчитала ключом a. Интересный запрос, да? Такое впечатление, что, поскольку ключом в исходной таблице являлась третья колонка, то Дельфы посчитали ключом третью колонку.
Перестановкой SELECT a, b, c, q... все исправилось. Я решил теперь использовать в таких (live) запросах только SELECT *.
Author: Nomadic
ID: 02584
Notebook как контейнер для форм

=== Notebook как контейнер для форм ===
...у меня происходит утечка памяти при изменениях страниц в закладках NoteBook. 
Вы не "теряете" ресурсы, вы их используете. Вы ИСПОЛЬЗУЕТЕ ресурсы на каждой страницы начиная с первой, которая доступна для вашего созерцания. Я упомянаю это потому, потому что проблема ПОТЕРИ ресурсов относится к другому типу проблемы. 
Недавно я работал над проблемой показа других *ФОРМ* в главной форме, как если бы они были страницами NoteBook. Форма создается при перелистывании на эту "страницу", и разрушается при ее покидании. Это требует хранения неизменяемой информации, естественно, в главной форме, но это чрезвычайно нетребовательно к ресурсам. Главное, что вы храните поля индивидуальных данных в главной форме с именем "Child", а инициализируете в обработчике события экземпляра TForm2 (или имеющего другое имя, в зависимости от имени вашей первой дочерней формы) OnCreate. Поместите закладки в нижней части формы, и при изменении закладки освобождайте текущего "ребенка", а затем создавайте и делайте ребенком другой соответствующий экземпляр формы. 
Как заставить работать эту технологию: у каждой дочерней формы имеется метод CreateParams, позволяющий сделать ее "ребенком" главной формы:
procedure TPageForm.CreateParams(var Params: TCreateParams);
begin
 inherited CreateParams(Params);
 with Params do
 begin
 WndParent := Application.MainForm.Handle;
 Parent := Application.MainForm;
 Style := WS_CHILD or WS_CLIPSIBLINGS or WS_CLIPCHILDREN;
 Align := alClient;
 end;
end;
Код главной формы должен выглядеть примерно так:
procedure TForm1.TabSet1Change(Sender: TObject; NewTab: Integer; var AllowChange: Boolean);
begin
 LockWindowUpdate(Handle);
 Child.Free;
 case NewTab of
 0: Child := TForm2.Create(Application);
 1: Child := TForm3.Create(Application);
 2: Child := TForm4.Create(Application);
 end;
 Child.Show;
 LockWindowUpdate(0);
end;
Source: http://delphiworld.narod.ru/
ID: 01167
----
Кто-нибудь может мне помочь в вопросе размещения подклассов форм на страницах компонента TTabbedNotebook? 
Я пробовал следующий код и он отлично работает с компонентами, являющимися частью формы, содержащей TTabbedNotebook; тем не менее он не работает с дочерними формами:
ChildForml[i].Parent := TWinControl(BrowseTabNotebook.Pages.Objects[i]);
В дочерней форме должен быть следующий код:
private
 { Private }
 procedure CreateParams(var Params: TCreateParams); override;
implementation
procedure TChildForm1.CreateParams(var Params: TCreateParams);
begin
 { сначала вызываем унаследованные методы. }
 inherited CreateParams(Params);
 with Params do
 begin
 WndParent := Application.Mainform.Handle;
 Style := (Style or WS_CHILD) and not WS_POPUP;
 end;
end;
Source: http://delphiworld.narod.ru/
ID: 01168
ODBC соединения

=== ODBC соединения ===
...я обращал ваше внимание на трудности коннекта Delphi-приложений с Watcom. За исключением досадной проблемы с чувствительностью регистров у ODBC драйверов (которая пропадает после установки соответствующих заплаток), мое приложение действительно лучше соединяется с базой данных Watcom, чем LIBS. Вот функция, которую я использую для подключения к серверу:
function TLogonForm.LogonToServer: Boolean;
begin
 LogonToServer := FALSE;
 MyDatabase.AliasName := DatabaseEdit.Text;
 MyDatabase.Params.Values['USER NAME'] := UserIDEdit.Text;
 MyDatabase.Params.Values['PASSWORD'] := PasswordEdit.Text;
 MyDatabase.Params.Values['SERVER NAME'] := ServerName;
 try
 MyDatabase.Connected := TRUE;
 LogonToServer := TRUE;
 except
 on E: EDatabaseError do
 MessageDlg('Программа не в состоянии подключиться к серверу баз данных по следующей причине:' + #10 + #10 + E.Message, mtError, [mbOK], 0);
 end;
end;
Эта функция находится в модуле с формой диалога подключения, на которой расположены три поля редактирования: идентификатор пользователя, пароль и имя базы данных. При щелчке пользователем на кнопке OK, значение из поля с именем базы данных используется для поиска в файле ODBC.INI:
ServerName := ODBCIni.ReadString(DatabaseEdit.Text, 'Database', );
Этой строчкой мы получаем фактическое имя файла базы данных, к которому нам необходимо получить доступ ('SERVER NAME' - параметр соединения).
Во время разработки я выставил в своем компоненте TDatabase следующие параметры:
 Connected: FALSE
 DatabaseName: DCAC {это псевдоним, используемый приложением}
 KeepConnection: TRUE
 LoginPrompt: FALSE
 Name: MyDatabase
 TransIsolation: tiReadCommitted
AliasName, DriverName и Params в режиме проектирования остаются пусты, DriverName не используется совсем, т.к. во время выполнения приложения используется AliasName (они являются взаимоисключающими, вы можете установить что-то одно, но не оба сразу).
Вот секции Interbase и Watcom моего файла ODBC.INI:
 [DCAC_IB]
 Driver=C:\WIN\SYSTEM\BLINT04.DLL
 Description=DC Aquatics (Interbase)
 Database=D:\DCAC_IB\DCAC.GDB
 
 [DCAC_WSQL]
 Driver=D:\WSQL\wsqlodbc.dll
 Description=DC Aquatics (Watcom)
 Database=D:\DCAC_WAT\DCAC.DB
 Start=D:\wsql\db32w %d
Если мне необходимо подключиться к базе данных Watcom, все, что мне нужно сделать - изменить содержимое поля редактирования имени базы данных в диалоге подключения на 'DCAC_WSQL'. Если мне нужно использовать базу данных Interbase, я набираю 'DCAC_IB'. Работает замечательно.
Надеюсь это поможет... успехов...
Source: Взято с http://delphiworld.narod.ru
ID: 02677
OLE и Interbase - прочесть и записать

=== OLE и Interbase - прочесть и записать ===
procedure TForm1.ReadOLE;
var
 BS: TBlobStream;
begin
 BS := TBlobStream.Create(Table1BLOBFIELD_BLOB, bmRead);
 OLEContainer1.LoadFromStream(BS);
 BS.Free;
end;
procedure TForm1.WriteOLE;
var
 BS: TBlobStream;
begin
 BS := TBlobStream.Create(Table1BLOBFIELD_BLOB, bmWrite);
 OLEContainer1.SaveToStream(BS);
 BS.Free;
end;
Author: Rob Minte 
Source: Взято с http://delphiworld.narod.ru
ID: 02927
Category:Базы данных
Category:Interbase
OnColumnClick из TListView для TStringGrid

=== OnColumnClick из TListView для TStringGrid ===
{
 There are two routines to implement the OnColumnClick Methods for a TStringGrid.
 Set the first row as fixed and the Defaultdrawing to True.
}
type
 TForm1 = class(TForm)
 StringGrid1: TStringGrid;
 procedure StringGrid1MouseDown(Sender: TObject; Button: TMouseButton;
 Shift: TShiftState; X, Y: Integer);
 procedure StringGrid1MouseUp(Sender: TObject; Button: TMouseButton;
 Shift: TShiftState; X, Y: Integer);
 private
 zelle: TRect; // cell
 acol, arow: Integer;
 public
 end;
var
 Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.StringGrid1MouseDown(Sender: TObject; Button: TMouseButton;
 Shift: TShiftState; X, Y: Integer);
var
 Text: string;
begin
 with stringgrid1 do
 begin
 MouseRoCell(x, y, acol, arow);
 if (arow = 0) and (button = mbleft) then
 case acol of
 0..2:
 begin
 // Draws a 3D Effect (Push)
 // Zeichnet 3D-Effekt (Push)
 zelle := CellRect(acol, arow);
 Text := Cells[acol, arow];
 Canvas.Font := Font;
 Canvas.Brush.Color := clBtnFace;
 Canvas.FillRect(zelle);
 Canvas.TextRect(zelle, zelle.Left + 2, zelle.Top + 2, Text);
 DrawEdge(Canvas.Handle, zelle, 10, 2 or 4 or 8);
 DrawEdge(Canvas.Handle, zelle, 2 or 4, 1);
 end;
 end;
 end;
end;
procedure TForm1.StringGrid1MouseUp(Sender: TObject; Button: TMouseButton;
 Shift: TShiftState; X, Y: Integer);
var
 Text: string;
begin
 with StringGrid1 do
 begin
 // Draws a 3D-Effect (Up)
 // Zeichnet 3D-Effekt (Up)
 Text := Cells[acol, arow];
 if arow = 0 then
 begin
 Canvas.Font := Font;
 Canvas.Brush.Color := clBtnFace;
 Canvas.FillRect(zelle);
 Canvas.TextRect(zelle, zelle.Left + 2, zelle.Top + 2, Text);
 DrawEdge(Canvas.Handle, zelle, 4, 4 or 8);
 DrawEdge(Canvas.Handle, zelle, 4, 1 or 2);
 MouseToCell(zelle.Left, zelle.Top, acol, arow);
 end;
 end;
 if (arow = 0) and (Button = mbleft) then
 case acol of
 0..2:
 begin
 // Code to be executed...
 // Programmcode der ausgefuhrt werden soll
 ShowMessage('Column ' + IntToStr(acol));
 zelle := stringgrid1.CellRect(1, 1);
 end;
 end;
end;
end.
Source: http://delphiworld.narod.ru/
ID: 01104
Opening PowerPoint

Запуск PowerPoint
== Opening PowerPoint (early binding) ==
Before you can use this method, you must have imported the type library (MSPpt8.olb for PowerPoint 97).
One way of starting PowerPoint is to try the GetActiveObject call, to get a running instance of PowerPoint, but put a call to CoApplication.Create in an except clause. But except clauses are slow, and can cause problems within the IDE for people who like Break On Exceptions set to True. The following code removes the need for a try...except clause, by avoiding using OleCheck on GetActiveObject in the case when PowerPoint is not running.
uses Windows, ComObj, ActiveX, OfficePowerPoint_TLB;
var
 PowerPoint: _Application;
 AppWasRunning: Boolean; // tells you if you can close PowerPoint when you've finished
 Unknown: IUnknown;
 Result: HResult;
begin
 AppWasRunning := False;
 Result := GetActiveObject(CLASS_Application, nil, Unknown);
 if (Result = MK_E_UNAVAILABLE) then
 PowerPoint := CoApplication.Create
 else
 begin
 { make sure no other error occurred during GetActiveObject }
 OleCheck(Result);
 OleCheck(Unknown.QueryInterface(_Application, PowerPoint));
 AppWasRunning := True;
 end;
 PowerPoint.Visible := TOleEnum(msoTrue);
 ...
== Without using the type library ==
Automation is so much easier and faster using type libraries (early binding) that you should avoid managing without if at all possible. But if you really can't, here's how to get started:
var
 PowerPoint: Variant;
begin
 try
 PowerPoint := GetActiveOleObject('PowerPoint.Application');
 except
 PowerPoint := CreateOleObject('PowerPoint.Application');
 end;
 PowerPoint.Visible := True;
ID: 04464
Category:COM
Category:MS Office