Секция 4 из 5 - Предыдущая - Следующая
Все секции
- 1
- 2
- 3
- 4
- 5
Win32MajorVersion,
Win32MinorVersion,
Win32BuildNumber (в модуле SysUtils).
Инициализируются они автоматически, остается только проверить их.
Юрий Зотов
-+++++++++++++++++++++++++++++
DA> Может комy известен способ отличить Windows 2000 Server от Wks?
HKLM\System\CurrentControlSet\Control\ProductOptions
ProductType:REG_SZ (WinNT - Prof, ServerNT - Server, LanmanNT - сервер и
контроллер домена).
Именно по этому ключику сама винда определяет.
Это также относится и к NT4 (а может и ко всему остальному)
++++++++++++++++++++++++++++++
DA> Может комy известен способ отличить Windows 2000 Server от Wks?
Для определения версии Windows используем API-функцию
GetVersionEx(pOSVersionInfo), где pOSVersionInfo - указатель на структуру
следующего вида:
type
TOSVersionInfoEx = record
OsVersionInfoSize: DWORD; {Размер структуры типа TOSVersionInfo.
Поле обязательно должно быть заполнено перед вызовом GetVersionEx}
MajorVersion: DWORD; {основной номер версии ОС}
MinorVersion: DWORD; {дополнительный номер версии ОС}
BuildNumber: DWORD; {номер сборки ОС}
PlatformId: DWORD; {Идентификатор платформы}
CSDVersion: array [0..127] of char; {дополнительная текстовая
информация об установленной операционной системе}
//Далее идут поля, которые появились с выходом Windows 2000
ServicePackMajor: WORD; {основной номер service pack}
ServicePackMinor: WORD; {дополнительный номер service pack}
SuiteMask: WORD; {доступные программные пакеты; доступные
значения:
VER_SUITE_SMALLBUSINESS, VER_SUITE_ENTERPRICE,
VER_SUITE_BACKOFFICE,
VER_SUITE_COMUNICATIONS,
VER_SUITE_TERMINAL,VER_SUITE_SMALLBUSINESS_RESTRICTED,
VER_SUITE_EMBEDDEDNT,VER_SUITE_DATACENTER}
ProductType: Byte; {вариант ОС; принимает значения:
VER_NT_WORKSTATION, VER_NT_SERVER, VER_NT_DOMAIN_CONTROLLER}
Reserved: Byte; {зарезервировано для будущих версий ОС}
end;
Значения полей SuiteMask и ProductType смотри в MSDN, поскольку в
windows.pas, включая Delphi 7 описан старый вариант TOSVersionInfo (как с
этим обстоят дела в Delphi .NET).
Отсюда можно сделать вывод: или подправить windows.pas, или описывать самому
приведенную выше структуру (обрати внимание, что я специально назвал ее
TOSVersionInfoEx, чтобы не конфликтовать с TOSVersionInfo из windows.pas).
Может в jvcl поправили данную структуру.
Если ты уверен, что твой программный продукт будут использовать только на
платформах версий Windows 2000 и старше (включая Windows CE), тогда поле
CSDVersion объяви как массив WideChar и используй вызов API-функции
GetVersionExW.
Oleg Levkin <Oleg.Levkin@p6.f40.n5053.z2.fidonet.org>
------------------------------------------------------------
Q-115: Как помигать Scroll Lock?
------------------------------------------------------------
procedure TForm1.Timer1Timer(Sender: TObject);
begin
keybd_event(VK_SCROLL, 0, 0, 0);
keybd_event(VK_SCROLL, 0, vk_up, 0);
end;
++++++++++++++++++++++++++++
procedure TForm1.Timer1Timer(Sender: TObject);
begin
keybd_event(VK_SCROLL, MapVirtualKey(VK_SCROLL, 0) , 0, 0);
keybd_event(VK_SCROLL, MapVirtualKey(VK_SCROLL, 0), vk_up, 0);
end;
Leonid Troyanovsky <lv.t@eco-pro.ru>
------------------------------------------------------------
Q-116: Как из dll узнать узнать полный путь к этой dll.
------------------------------------------------------------
function GetModuleFileNameStr(Instance: THandle): String;
var
buffer : array [0..MAX_PATH] of Char;
begin
GetModuleFileName( Instance, buffer, MAX_PATH);
Result := buffer;
end;
GetModuleFileNameStr(Hinstance); // dll name
GetModuleFileNameStr(0); // exe name
Leonid Troyanovsky <lv.t@eco-pro.ru>
------------------------------------------------------------
Q-117: Как отобразить каталог?
------------------------------------------------------------
ListBox1.Perform(LB_DIR, 0, LParam(PChar('*.*')));
------------------------------------------------------------
Q-118: Как узнать кол-во цветов цветовой палитры?
------------------------------------------------------------
function GetColorsCount : DWord;
var
DC : HDC;
begin
DC := GetDC( 0 );
Win32Check(DC <> 0);
Result :=1 shl (GetDeviceCaps(DC, PLANES) *
GetDeviceCaps(DC, BITSPIXEL));
ReleaseDC( 0, DC );
end;
Leonid Troyanovsky <lv.t@eco-pro.ru>
------------------------------------------------------------
Q-119: Как ввести текст в "чужой" Edit?
------------------------------------------------------------
SendMessage(EditHandle, WM_SETTEXT, 0, LParam(PChar('MyText')));
------------------------------------------------------------
Q-120: Как заставить мигать кнопку приложения на AppBar?
------------------------------------------------------------
procedure TForm1.Timer1Timer(Sender: TObject);
begin
FlashWindow(Application.Handle, True);
end;
Leonid Troyanovsky <lv.t@eco-pro.ru>
------------------------------------------------------------
Q-121: Как сделать программу без главной формы?
------------------------------------------------------------
program Project1;
uses
Dialogs;
begin
ShowMessage('Is there anybody out there ?' );
end.
------------------------------------------------------------
Q-122: Как убрать VerticalScrollBar из TListBox навсегда?
------------------------------------------------------------
procedure TListBoxForEver.CreateParams (var Params:
TCreateParams); //override
begin
inherited CreateParams(Params);
Params.Style := Params.Style and not WS_VSCROLL;
end;
Leonid Troyanovsky <lv.t@eco-pro.ru>
------------------------------------------------------------
Q-123: Как показать диалог выбора директории?
------------------------------------------------------------
из модуля FileCtrl.
1. function SelectDirectory(const Caption: string; const Root: WideString;
out Directory: string): Boolean; overload;
2. function SelectDirectory(var Directory: string; Options: TSelectDirOpts;
HelpCtx: Longint): Boolean; overload;
из RxLib
TDirectoryEdit
function GetDirectory(nFolder: Longint): String;
var
Bi : TBrowseInfo;
lpName: array [0..MAX_PATH] of Char;
ppidl, aItemLst : PItemIDList;
begin
SHGetSpecialFolderLocation(Application.Handle, nFolder, ppidl);
FillChar(Bi, SizeOf(bi), 0);
Bi.hwndOwner := Application.Handle;
Bi.pidlRoot := ppidl;
Bi.pszDisplayName := lpName;
Bi.lpszTitle := 'Open directory';
aItemLst := SHBrowseForFolder(Bi);
CoTaskMemFree(ppidl);
SHGetPathFromIDList(aItemLst, lpName);
CoTaskMemFree(aItemLst);
Result := lpName;
end;
Пример использования (иначе не поймут, что такое nFolder)
// значения nFolder можно найти в описании
// к SHGetSpecialFolderLocation
// из Win32 Programmer's Reference (win32.hlp)
procedure TForm1.Button1Click(Sender: TObject);
begin
Caption := GetDirectory(CSIDL_DRIVES);
end;
------------------------------------------------------------
Q-124: Как убрать из ListView горизонтальный скролбар навсегда?
------------------------------------------------------------
type
TNoHScrollListview = Class( TListview )
private
Procedure WMNCCalcSize( Var msg: TMessage ); message WM_NCCALCSIZE;
end;
procedure TNoHScrollListview.WMNCCalcSize(var msg: TMessage);
var
style: Integer;
begin
style := getWindowLong( handle, GWL_STYLE );
If (style and WS_HSCROLL) <> 0 Then
SetWindowLong( handle, GWL_STYLE, style and not WS_HSCROLL );
inherited;
end;
by Peter Below
------------------------------------------------------------
Q-125: Кaк искать oкнo по части eгo нaзвaния?
------------------------------------------------------------
function FindNextWnd(StartHWND: HWND; AString : String): HWND;
var
Buffer : array [0..255] of char;
begin
Result := StartHWND;
repeat
Result := FindWindowEx(0, Result, nil, nil);
GetWindowText(Result, Buffer, SizeOf(Buffer));
if StrPos(StrUpper(Buffer), PChar(UpperCase(AString))) <> nil
then Break;
until (Result = 0);
end;
------------------------------------------------------------
Q-126: Как обнаружить активность юзера?
------------------------------------------------------------
Application.OnMessage := DoMessageEvent;
procedure TForm1.DoMessageEvent ( var Msg: TMsg;
var Handled: Boolean);
begin
case Msg.message of
WM_KEYFIRST..WM_KEYLAST,
WM_MOUSEFIRST..WM_MOUSELAST:
{Произошли события клавиатуры и мыши};
..
end;
end;
Leonid Troyanovsky <lv.t@eco-pro.ru>
------------------------------------------------------------
Q-127: Как yзнать текущую Ru/En pаскладкy клавиатypы?
------------------------------------------------------------
GetKeyboardLayoutName(buffer{:array [0..KL_NAMELENGTH] of Char});
case ((StrToInt('$'+ Buffer)) and $03FF) of
LANG_ENGLISH: Caption := 'Eng';
LANG_RUSSIAN: Caption := 'Rus';
end;
++++++++++++++++++++++++++++
procedure TForm1.Button1Click(Sender: TObject);
var
AklName: array [0..2] of Char;
begin
GetLocaleInfo( LoWord(GetKeyboardLayout(0)),
LOCALE_SABBREVLANGNAME,
AklName,
SizeOf(AklName));
Caption := AklName;
end;
Leonid Troyanovsky <lv.t@eco-pro.ru>
------------------------------------------------------------
Q-128: Как передать строку другому приложению?
------------------------------------------------------------
получатель:
procedure ReceiveMessage (var Msg: TMessage); message WM_COPYDATA;
...
procedure TFormReceive.ReceiveMessage;
var
pcd : PCopyDataStruct;
begin
pcd := PCopyDataStruct(Msg.LParam);
Caption := PChar(pcd.lpData);
end;
отправитель:
procedure TFormXXX.Button1Click(Sender: TObject);
var
cd : TCopyDataStruct;
begin
cd.cbData := Length(Edit1.Text)+1;
cd.lpData := PChar(Edit1.Text);
SendMessage ( FindWindow('TFormReceive', nil),
WM_COPYDATA,
0,
LParam(@cd));
end;
Leonid Troyanovsky <lv.t@eco-pro.ru>
------------------------------------------------------------
Q-129: Как RichEdit сделать скролл на конец текста?
------------------------------------------------------------
with RichEdit do begin
SelLength := 0;
SelStart := Length(Text);
Perform(EM_SCROLLCARET,0,0);
end;
------------------------------------------------------------
Q-130: Удаление файлов из временного каталога, безопасно ли?
------------------------------------------------------------
При получении имени папки предназначенной для хранения временных файлов
могут возникнуть некоторые проблемы.
>> Прекрасно это выглядит, когда в качестве каталога временных файлов
>> назначен например C:\Windows
> :-) Я и говорю что небезопасно.
Особенно пикантно это выглядит, в свете того, что
Remarks
Windows 95/98/Me: The GetTempPath function gets the temporary file
path as follows:
The path specified by the TMP environment variable. The path specified by
the TEMP environment variable, if TMP is not defined or if TMP specifies a
directory that does not exist. The current directory, if both TMP and TEMP
are not defined or specify nonexistent directories.
Этак переименовываешь C:\TEMP - и программа чистит текущий каталог :-)
Windows NT/2000 or later: The GetTempPath function does not verify that the
directory specified by the TMP or TEMP environment variables exists. The
function gets the temporary file path as follows:
The path specified by the TMP environment variable. The path specified by
the TEMP environment variable, if TMP is not defined. The Windows
directory, if both TMP and TEMP are not defined.
Этак удаляешь переменные окружения - и программа "деинсталлирует" Windows
Из этого вытекает следующее, удаление файлов из любого каталога, особенно из
временного чрезвычайно опасная операция, не ты создал - не трогай. Удалять
только ручками, глядя на файлы и принимая решения индивидуально по каждому
файлу.
При использовании функции GetTempPath проверить если подстрока TEMP в
результате и в случае отсутствия вхождения запросить пользователя для
принятия решения, с рекомендацией создать каталог TEMP и необходимые
переменные среды, лучше посоветоваться обратиться к администратору для
принятия решения. Это простое правило позволит избежать серьезных
последствий.
Тенцер А.Л. <tolik@katren.nsk.ru>
Andrew V. Fionik <fionika@chat.ru>
Anatoly Podgoretsky <anatoly@podgoretsky.com>
------------------------------------------------------------
Q-131: Как узнать состояние управляющих клавиш - Shift, Ctrl, Alt?
------------------------------------------------------------
function IsKeyDown(vk: Word):Boolean;
begin
Result := GetKeyState(vk) and $8000 = $8000;
end;
vk для Ctrl, Shift, Alt соответственно равны: vk_control, vk_shift и vk_menu
------------------------------------------------------------
Q-132: Как сохранить всю форму в файл (как Delphi в *.dfm)?
------------------------------------------------------------
constructor TForm1.Create(AOwner: TComponent); // override;
var
fname: String;
begin
{ Для динамически создаваемых контролов, может требоваться
RegisterClasses(..); }
fname := FormFilename;
if FileExists( fname ) then
begin
CreateNew(AOwner);
ReadComponentResFile(fname, Self);
end
else
inherited Create( AOwner );
end;
procedure TForm1.FormCloseQuery( Sender: TObject;
var CanClose: Boolean);
begin
WriteComponentResFile(FormFileName, Self);
end;
{Peter Below, Vladimir Titov}
------------------------------------------------------------
Q-133: Как контрол может сам себя разрушить?
------------------------------------------------------------
TMyWinControl = class(TWinControl)
private
procedure WMuser1(var msg: TMessage); message WM_USER+1;
...
public
procedure Release;
...
end;
procedure TMyWinControl.WMuser1;
begin
Free;
end;
procedure TMyWinControl.Release;
begin
PostMessage(Handle, WM_USER+1, 0, 0);
end;
------------------------------------------------------------
Q-134: Как отследить переход фокуса в приложении?
------------------------------------------------------------
procedure TForm1.AppControlChange(Sender: TObject);
begin
if Sender is TScreen then
Caption := TScreen(Sender).ActiveForm.ActiveControl.Name;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Screen.OnActiveControlChange := AppControlChange;
end;
Leonid Troyanovsky <lv.t@eco-pro.ru>
------------------------------------------------------------
Q-135: Как заставить MediaPlayer крутить один и тот же клип?
------------------------------------------------------------
procedure TForm1.WMUser1(var msg:TMessage);// message WM_USER+1;
begin
with MediaPlayer1 do begin
Previous;
Notify := True;
Play;
end;
end;
procedure TForm1.MediaPlayer1Notify(Sender: TObject);
begin
if (Sender as TMediaPlayer).NotifyValue = nvSuccessful then
PostMessage(Handle, WM_USER+1, 0, 0);
end;
------------------------------------------------------------
Q-136: Как назначить процедуру собственному пункту системного меню?
------------------------------------------------------------
const
cm_mycommand = $00A0;
procedure TForm1.FormCreate(Sender: TObject);
var HSysMenu: HMENU;
begin
HSysMenu:=GetSystemMenu(Handle,FALSE);
InsertMenu( HSysMenu, 0, MF_BYPOSITION or MF_STRING,
cm_mycommand, 'MyString');
end;
procedure TForm1.WMSysCommand (var Message:
TWMSysCommand); // message WM_SYSCOMMAND;
begin
case Message.CmdType of
cm_mycommand: ShowMessage('My Command');
else
inherited;
end;
end;
Leonid Troyanovsky <lv.t@eco-pro.ru>
------------------------------------------------------------
Q-137: Какой класс окна у консоли?
------------------------------------------------------------
'tty' for 9x
'ConsoleWindowClass' for NT
------------------------------------------------------------
Q-138: Какое сообщение надо отлавливать в Application.OnMessage для
отслеживания клавиши Alt (vk_menu)
------------------------------------------------------------
WM_SYSKEYDOWN/WM_SYSKEYUP
------------------------------------------------------------
Q-139: Как спрятать контрол, если известен его Handle?
------------------------------------------------------------
ShowWindow(ButtonHandle, SW_HIDE); // SW_SHOW
------------------------------------------------------------
Q-140: Как поменять иконку и стpокy в заголовке консольного окна?
------------------------------------------------------------
procedure TForm1.Button1Click(Sender: TObject);
var
h : HWND;
AIcon : TIcon;
begin
AllocConsole;
SetConsoleTitle(PChar('Console Title'));
Sleep(0);
h := FindWindow(nil, PChar('Console Title'));
AIcon := TIcon.Create;
ImageList1.GetIcon(0, AIcon);
SendMessage(h, WM_SETICON, 1, AIcon.Handle);
AIcon.Free;
end;
Leonid Troyanovsky <lv.t@eco-pro.ru>
------------------------------------------------------------
Q-141: Как сделать окно без VCL?
------------------------------------------------------------
program Project1;
{ Copyright (c) 1996 by Charlie Calvert
Standard Windows API application written in Object Pascal.
No VCL code included. This is all done on the Windows API
level.
Note that you need to include both Windows and Messages!}
uses
Windows, Messages;
const
AppName = 'Window1';
function WindowProc(Window: HWnd; AMessage, WParam,
LParam: Longint): Longint; stdcall;
begin
WindowProc := 0;
case AMessage of
wm_Destroy: begin
PostQuitMessage(0);
Exit;
end;
end;
WindowProc := DefWindowProc(Window, AMessage, WParam, LParam);
end;
{ Register the Window Class }
function WinRegister: Boolean;
var
WindowClass: TWndClass;
begin
WindowClass.Style := cs_hRedraw or cs_vRedraw;
WindowClass.lpfnWndProc := @WindowProc;
WindowClass.cbClsExtra := 0;
WindowClass.cbWndExtra := 0;
WindowClass.hInstance := HInstance;
WindowClass.hIcon := LoadIcon(0, idi_Application);
WindowClass.hCursor := LoadCursor(0, idc_Arrow);
WindowClass.hbrBackground := HBrush(Color_Window);
WindowClass.lpszMenuName := nil;
WindowClass.lpszClassName := AppName;
Result := RegisterClass(WindowClass) <> 0;
end;
{ Create the Window Class }
function WinCreate: HWnd;
var
hWindow: HWnd;
begin
hWindow := CreateWindow(AppName, 'Object Pascal Window',
ws_OverlappedWindow, cw_UseDefault, cw_UseDefault,
cw_UseDefault, cw_UseDefault, 0, 0, HInstance, nil);
if hWindow <> 0 then begin
ShowWindow(hWindow, CmdShow);
UpdateWindow(hWindow);
end;
Result := hWindow;
end;
var
AMessage: TMsg;
hWindow: HWnd;
begin
if not WinRegister then begin
MessageBox(0, 'Register failed', nil, mb_Ok);
Exit;
end;
hWindow := WinCreate;
if hWindow = 0 then begin
MessageBox(0, 'WinCreate failed', nil, mb_Ok);
Exit;
end;
while GetMessage(AMessage, 0, 0, 0) do begin
TranslateMessage(AMessage);
DispatchMessage(AMessage);
end;
Halt(AMessage.wParam);
end.
------------------------------------------------------------
Q-142: Как избежать повторного запуска моего приложения?
------------------------------------------------------------
type
TForm1 = class(TForm)
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
procedure WMCopyData(var msg: TMessage); message WM_COPYDATA;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
uses
checkinst;
procedure TForm1.FormCreate(Sender: TObject);
var
h : HWND;
begin
h := SetUniqueUID(Handle, 123456); // назначаем уникальный идентификатор
if h <> Handle then
begin
SendString(h, GetCommandLineStr, Handle, 0);
ActivatePrevInstance(h);
Halt;
end;
end;
procedure TForm1.WMCopyData;
begin
Memo1.Lines.CommaText := PChar(PCopyDataStruct(msg.LParam).lpData);
end;
--------------------------checkinst.pas-------------------------
unit checkinst;
interface
uses
Windows,
Messages,
Sysutils;
function SetUniqueUID(ahwnd: HWND; uid: DWord): HWND;
procedure ActivatePrevInstance(ahwnd: HWND);
procedure SendString(ahwnd:HWND; const s: String; aWParam: WParam;
dwData:DWord);
function GetCommandLineStr: String;
implementation
function SetUniqueUID(ahwnd: HWND; uid: DWord): HWND;
var
ClassName: array [0..255] of Char;
begin
GetClassName(ahwnd, ClassName, SizeOf(classname));
Result := FindWindowEx(0, 0, ClassName, nil);
while (Result <> 0) do
if GetProp(Result, 'UID') = uid then
Exit
else
Result := FindWindowEx(0, Result, ClassName, nil);
SetProp(ahwnd, 'UID', uid);
Result := ahwnd;
end;
procedure ActivatePrevInstance(ahwnd: HWND);
var
h : HWND;
begin
h := GetWindowLong(ahwnd, GWL_HWNDPARENT);
if IsIconic(h) then
ShowWindow(h, SW_RESTORE);
SetForegroundWindow(h);
end;
procedure SendString(ahwnd:HWND; const s: String; aWParam: WParam;
dwData:DWord);
var
cds: TCopyDataStruct;
begin
cds.cbData := Length(s)+1;
cds.lpData := Pointer(s);
cds.dwData := dwData;
SendMessage(ahwnd, WM_COPYDATA, aWParam, LParam(@cds));
end;
function GetCommandLineStr: String;
var
i : Integer;
begin
for i := 0 to ParamCount do
Result := Result + ' ' + AnsiQuotedStr(ParamStr(i), '"');
end;
-------------------------EOF checkinst.pas---------------------
Leonid Troyanovsky <lv.t@eco-pro.ru>
++++++++++++++++++++++++++++++++++++
=== Вариант с Мьютексом ===
В файле проекта (.dpr) прямо можешь написать нечто вроде:
uses windows,...
var
H: THandle;
begin
H := CreateMutex(nil, True, 'уникальное_имя_для_твоей_проги');
if GetLastError = ERROR_ALREADY_EXISTS then
begin
H := FindWindow(nil, 'название заголовка окна программы');
SetForegroundWindow(H);
Exit;
end;
Application.Initialize;
Application.Title := 'название заголовка окна программы';
Application.CreateForm(TAppData, AppData);
Application.CreateForm(TMain, Main);
Application.Run;
CloseHandle(H);
end;
Прочко Денис Владимирович.
sysadmin@)farmeko.khv.ru
++++++++++++++++++++++++++++++++++++
Если быстро запустить дважды приложение, то вариант с поиском по классу окна
может не сработать, так как окно еще не успеет создаться
Анатолий Подгорецкий
------------------------------------------------------------
Q-143: Как записать массив в файл?
------------------------------------------------------------
with TFileStream.Create('array.dat', fmCreate or fmOpenWrite) do begin
WriteBuffer(a, SizeOf(a));
Free;
end;
------------------------------------------------------------
Q-144: Delphi 6 требует Proxies.pas?
------------------------------------------------------------
{$ifdef D_6_UP} // Это моя константа
DesignIntf, DesignEditors, DesignWindows, DsnConst,
{$else}
DsgnIntf,
{$endif}
Eugene Mayevski <mayevski@eldos.org>
------------------------------------
Вопрос: Файл designeditors.pas использует 'proxies' в uses.
Исходный текст (proxies.pas) или откомпилированный модуль (proxies.dcu)
нигде не находится ни на моем жеском диске ни на D6 Pro CD..
Просто реорганизуйте ваш проект на использование runtime пакетов и добавьте
"DesignIDE" к вашемк списку runtime пакетов. Proxies находится здесь, и вам
не нужен исходный текст вообще.
Почему это сделано? Просто доя уверенности, что вы не сможете распространять
design time части (property editors, component editors), это запрещено по
личензии. DesignIDE.bpl не является свободно распространяемым, вы имеете
право использовать его только на машине на которой установлена Delphi,
подобно Component libraries.
forums.borland.com
------------------------------------------------------------
Q-145: О библиотеке RxLib
------------------------------------------------------------
На сайте delphiplus.org в разделе Бесплатно|RXLibrary
(http://delphiplus.spils.lv/RXLibrary.html) лежит RX Library 2.75 с help'ами
и четырьмя неофициальными портами RX Library 2.75 под Delphi 6:
1. Версия 1.1 (1.18M) от Oxygen Software
2. Версия 1 (1.36M) от Dennis Ortiz
3. Патч на RxLib версия 1.5 (437K) от Polaris Software
4. Версия от Epsylon Technologies
Anatoly Podgoretsky wrote:
>
> Hi, Delphi Plus!
> You wrote to Anatoly Podgoretsky on Tue, 20 Nov 2001 16:00:55 +0000 (UTC):
>
DP>> 14.11.2001 в раздел "Бесплатно|Компоненты" выложен четвертый
DP>> неофициальный порт RX Library 2.75 под Delphi 6 (от Epsylon
DP>> Technologies).
>
DP>> http://www.delphiplus.org - ежедневные новости информационных
DP>> технологий http://www.faq.delphiplus.org - коллекция FAQ по Delphi
>
> Прекрасно, этим я больше доверяю, а как вообще насчет характеристики всех
> четырех портов, а то у людей глаза разбегаются :-)
Epsylon Technologies
*************************
Здравствуйте!
Мы были вынуждены сделать свой вариант RxLib потому, что остальные нас
немного не устраивали.
Сразу скажу, зачем нам вообще нужна библиотека RxLib - она используется в
нашем продукте в качестве некоего примера всем известных компонентов.
Поэтому к такой библиотеке с нашей стороны предъявлялось требование
максимальной стандартности, если можно применить такой термин. Кроме того,
наш продукт поддерживает несколько версий Delphi и C++Builder, поэтому от
такой библиотеки требуется одновременная поддержка всех нужных нам версий
компиляторов.
Естественно, мы рассматривали варианты использования уже готовой работы по
адаптированию библиотеки под Delphi 6.0.
Однако:
- вариант от Polaris заточен для использования пакета Polaris Library.
Туда что-то добавлено, что-то починено, что-то переделано. Иначе
говоря, этот вариант не может быть стандартным;
- вариант от Oxygen является версией ТОЛЬКО под Delphi 6.0, содержит ряд
мелких неточностей при переводе design-time кода. Также там что-то
изменено по сравнению с 2.75. Кроме того, не переименован модуль
AppUtils.pas;
- вариант от Dennis Ortiz также является версией только под Delphi 6.0.
Ничего не могу сказать про нее - мы туда глубоко не заглядывали.
Не совсем понятно, зачем выкидывать из библиотеки возможность поддержки
предыдущих версий Delphi, когда добавить вариант кода для Delphi 6.0 ничуть
не сложнее. Никто также не против исправления каких-либо ошибок в
библиотеке, но давайте делать это централизованно, если уж авторы забили на
свое детище. Например, через тот же Source Forge.
Наш вариант основан на общедоступном коде, и содержит модули из 2.75,
включая update от 16.12.1999 и патч для C+Builder 5.0 от 30.05.2000. В эти
модули добавлена возможность работы под Delphi 6.0, в том числе добавлен
макрос RX_D6 и переименованы модули AppUtils и StrUtils. Все. Ничего больше.
Никакая старая функциональность не удалена, никакие баги не чинились. Полдня
работы.
==
Andrey Dementyev, Epsylon Technologies, http://www.epsylontech.com
Chief Software Architect
Информация от delphiplus
********************************
1. C 19-ого декабря компания SGB Software совместно с Ником Ходж (Nick
Hodges) из Borland support team займется дальнейшим развитием RxLib.
Надеются выпустить 3-ю версию к середине марта 2002 года. Все желающие могут
принять участие в этой работе, для этого достаточно написать на
RxLIb@SGBSoftware.com.
2. На DelphiPlus выложен материал "A где сейчас RXLib?" - заметка написанная
по материалам переписки в эхе fido7.ru.delphi. Наконец эта история получила
завершение, афера SGB Software лопнула, но RXLib не погибла, а вошла в
состав более крупного проекта Jedi Code Library, за эти руки нет опасения,
все подробности на сайте delphiplus.org, благодаря которому мы были постянно
в курсе событий всех приключений с RXLib, спасибо.
------------------------------------------------------------
Q-146: Как хранить настройки программ.
------------------------------------------------------------
Нижеприведенный текст являет собой вольное изложение отдельных статей
февральского выпуска Microsoft Platform SDK. Год 2001 от рождества Христова.
При проектировании способов хранения настроек своей программы следует
задаться тремя вопросами:
Что хранить.
Где хранить.
Как хранить.
Что хранить
Поскольку первая часть вопроса нам известна по определению, т.е. хранить мы
будем настройки программы, то перейдем ко второй части вопроса. Ваша
программа устанавливается на КОМПЬЮТЕР а пользуются ей ПОЛЬЗОВАТЕЛИ.
Соответственно все настройки разделяются на две части а то и на все три -
настройки которые относятся к компьютеру в целом, настройки которые
относятся ко всем локальным пользователям, настройки которые относятся к
конкретному пользовател. В зависимости от специфики программы первая и
вторая часть могут быть совмещены или разделены.
Поэтому важно сделать логическое разделение - какие настройки вашей
программы действительно специфичны для самого ПК, какие настройки должны
прилагаться ко всем пользователям, какие должны прилагаться к конкретному
пользователю. Кроме того Микрософт рекомендует чтобы настройки учитывали
возможную мобильность пользователя, т.е. для пользователя находящегося в
разных местах, возможно потребуется иметь разные наборы настроек.
Где хранить
Вообще в голову приходят три вещи.
Хранить настройки в системном реестре.
Хранить настройки в каталоге куда установлена программа.
Хранить настройки в системном каталоге Windows.
Хранить настройка в домашнем каталоге пользователя.
В Windows имеется три места предназначенных для хранения настроек которыми и
следует пользоваться.
Системный реестр
Домашний каталог пользователя (точнее один из его подкаталогов)
Общий каталог для пользователей
Прочие мысли о местах хранения настроек должны быть выброшены из голов как
вредные и противоестественные, Microsoft уже за вас все придумала и нефиг
извращаться. Для тех кто не понимает почему, объясняю. На нормальной ОС
(W'NT, W'2K) программа обычно запускается от имени и с правами конкретного
пользователя. Обычно, если этот пользователь не является администратором, он
имеет право изменять содержимое следующих ресурсов:
часть реестра HKEY_CURRENT_USER\*
содержимое своего домашнего каталога
содержимое временного каталога (который как правило находится внутри
домашнего)
содержимое некого каталога или каталогов специально выделенного для этого
администратором
При нормальном (читайте параноидальном) администрировании системы прочие
места либо доступны только в режиме чтения, либо вообще недоступны. В том
числе и папки \Program Files и Windows. Посему любая попытка программы
изменять любые файловые ресурсы окромя вышеуказанных черевата тем что ее
(программу) и его (пользователя) пошлют подальше. Причем далеко не в самой
вежливой форме.
Пример
Adobe Photoshop и его разработчики наивно полагают что им должны быть выданы
эксклюзивные права мусорить своими scratch-файлами в корневых каталогах
дисков, кроме того они полагают что им должна быть выдана в пользование в
режиме полный доступ часть системного реестра.. Временных каталогов,
специально выделенных для подобоного рода занятий, их не устраивает. Как
результат - Photoshop имеет серьезные проблемы с работой под Windows
NT/2000.
Системный реестр
С точки зрения хранения настроек программы системный реестр разделен на две
Секция 4 из 5 - Предыдущая - Следующая
© faqs.org.ru