b: boolean;
begin
s := Trim(InputBox('Новый пароль', 'Пароль', 'masterkey'));
b := s <> '';
s1 := s;
if b then b := InputQuery('Повторите пароль', 'Пароль', s1);
if not b or (s1 <> s) then ShowMessage('Пароль неверен');
end;
Текст на кнопках MessageDlg
Как можно сменить текст на кнопках диалогового окна MessageDlg? Английский язык для текста кнопок пользователь хочет заменить на родной.
Текст кнопок извлекается из списка строк, расположенных в файле …DELPHISOURCEVCLCONSTS.PAS. Отредактируйте его, после чего пересоберите VCL.
-Steve Schafer
Дополнение
VS дополняет:
Но можно ничего не менять. Вместо MessageDlg использовать MessageBox – функция WINDOWS. И, если ваш WINDOWS русифицирован, то надписи на кнопках в диалоговых окнах будут на русском языке.
Почитайте про Open Dialog Box (диалоговое окно открытия файла) в файле помощи Windows API. Ознакомьтесь в статье с описанием аргумента lpTemplateName. Главное, вы можете создать новое диалоговое окно для Open Dialog Box и заменить стандартный диалог вашим собственным.
Как вывести диалог выбора каталога?
Nomadic советует:
A: (DS): SelectDirectory, rxLib: TDirectoryEdit.
Как послать самостийное сообщение всем главным окнам в Windows?
Nomadic советует:
Пример:
Var FM_FINDPHOTO: Integer;
// Для того, чтобы использовать hwnd_Broadcast нужно сперва зарегистрировать уникальное
// сообщение.
Initialization
FM_FindPhoto:=RegisterWindowMessage('MyMessageToAll');
// Чтобы поймать это сообщение в другом приложении (приёмнике) нужно перекрыть DefaultHandler
procedure TForm1.DefaultHandler(var Message);
begin
with TMessage(Message) do begin
if Msg = Fm_FindPhoto then MyHandler(WPARAM,LPARAM)
else Inherited DefaultHandler(Message);
end;
end;
// А теперь можно в приложении-передатчике
SendMessage(HWND_BROADCAST, FM_FINDPHOTO, 0, 0);
Кстати, для посылки сообщения дочерним контролам некоего контрола можно использовать метод Broadcast.
Как избавиться от торможения модальных окон?
Igor Nikolaev aKa The Sprite советует:
Hемодальные диалоговые окна, находящиеся на экране во время выполнения длительных операций,могут реагировать на действия пользователя очень медленно. Это ограничение Windows, и обойти его можно так:
while Flag do begin
PerformOperation;
Application.ProcessMessages;
Flag:=ContinueOperation;
end;
Моя программа довольно долго делает какую-то полезную работу, типа чтения дерева каталогов или обильных вычислений, и в этот момент почти не работают остальные программы. Как разрешить им это делать?
Nomadic отвечает:
A: Application.ProcessMessages.
(AA): Если вы хотите отдавать timeslices в нитях, пользуйтесь Sleep(0); это отдаст остаток слайса системе.
(Win16) Если вы хотите разрешить отработку сообщений другим программам, но не вашей, то лучше пользоваться Yield().
По моему глубокому убеждению для получения метки диска в среде Win95 необходимо использовать FindFile. Но это не работает, так?
Правильно, FindFile в Win32 больше не возвращает имя диска, поскольку в не-FAT файловых системах (например, в NTFS) это работает иначе, чем в FAT. Вместо этого используйте функцию API GetVolumeInformation.
– Peter Below
Восстанавление длинных имен файлов по известным коротким
boris советует:
//---------------------------------------------------------------------
// Восстанавливает длинные имена файлов по известным коротким (8.3)
// В качестве аргумента принимает полный или неполный (в т.ч. относительный)
// путь к файлу, например 'C:WINDOWSРАБОЧИ~1ИТАКДА~1.LNK' или
// '....COMMON~1BORLAN~1BDEBDEREA~1.TXT'. Понимает сетевые имена.
// Возвращает полный(!) путь типа 'C:WindowsРабочий столи так далее.lnk',
// 'C:Program FilesCommon FilesBorland SharedBDEbdereadme.txt',
// '\ComputerresourceFolder with long nameFile with long name.ext'
//---------------------------------------------------------------------
Function RestoreLongName(fn: string): string;
function LookupLongName(const filename: string): string;
var sr: TSearchRec;
begin
if FindFirst(filename, faAnyFile, sr)=0 then Result:=sr.Name
else Result:=ExtractFileName(filename);
SysUtils.FindClose(sr);
end;
function GetNextFN: string;
var i: integer;
begin
Result:='';
if Pos('\', fn)=1 then begin
Result:='\';
fn:=Copy(fn, 3, length(fn)-2);
i:=Pos('', fn);
if i<>0 then begin
Result:=Result+Copy(fn,1,i);
fn:=Copy(fn, i+1, length(fn)-i);
end;
end;
i:=Pos('', fn);
if i<>0 then begin
Result:=Result+Copy(fn,1,i-1);
fn:=Copy(fn, i+1, length(fn)-i);
end else begin
Result:=Result+fn;
fn:='';
end;
end;
Var name: string;
Begin
fn:=ExpandFileName(fn);
Result:=GetNextFN;
Repeat
name:=GetNextFN;
Result:=Result+''+LookupLongName(Result+''+name);
Until length(fn)=0;
End;
Как указать системе на необходимость сбросить буфера *.INI-файла на диск?
Nomadic советует:
procedure FlushIni(FileName: string);
var
{$IFDEF WIN32}
CFileName: array[0..MAX_PATH] of WideChar;
{$ELSE}
CFileName: array[0..127] of Char;
{$ENDIF}
begin
{$IFDEF WIN32}
if (Win32Platform = VER_PLATFORM_WIN32_NT) then begin
WritePrivateProfileStringW(nil, nil, nil, StringToWideChar(FileName, CFileName, MAX_PATH));
end else begin
WritePrivateProfileString(nil, nil, nil, PChar(FileName));
end;
{$ELSE}
WritePrivateProfileString(nil, nil, nil, StrPLCopy(CFileName, FileName, SizeOf(CFileName) – 1));
{$ENDIF}
end;
Nomadic советует:
Можно так:
procedure CopyFile(const FileName, DestName: TFileName);
var
CopyBuffer: Pointer; { buffer for copying }
TimeStamp, BytesCopied: Longint;
Source, Dest: Integer; { handles }
Destination: TFileName; { holder for expanded destination name }
const
ChunkSize: Longint = 8192; { copy in 8K chunks }
begin
Destination := ExpandFileName(DestName); { expand the destination path }
if HasAttr(Destination, faDirectory) then { if destination is a directory... }
Destination := Destination + '' + ExtractFileName(FileName); { ...clone file name }
TimeStamp := FileAge(FileName); { get source's time stamp }
GetMem(CopyBuffer, ChunkSize); { allocate the buffer }
try
Source := FileOpen(FileName, fmShareDenyWrite); { open source file }
if Source < 0 then raise EFOpenError.Create(FmtLoadStr(SFOpenError, [FileName]));
try
Dest := FileCreate(Destination); { create output file; overwrite existing }
if Dest < 0 then raise EFCreateError.Create(FmtLoadStr(SFCreateError, [Destination]));
try
repeat
BytesCopied := FileRead(Source, CopyBuffer^, ChunkSize); { read chunk }
if BytesCopied > 0 then { if we read anything... }
FileWrite(Dest, CopyBuffer^, BytesCopied); { ...write chunk }
until BytesCopied < ChunkSize; { until we run out of chunks }
finally
FileClose(Dest); { close the destination file }
{ SetFileTimeStamp(Destination, TimeStamp);} { clone source's time stamp }{!!!}
end;
finally
FileClose(Source); { close the source file }
end;
finally
FreeMem(CopyBuffer, ChunkSize); { free the buffer }
end;
FileSetDate(Dest,FileGetDate(Source));
end;
Хм. IMHO крутовато будет такие функции писать, когда в большинстве случаев достаточно что-нубудь типа нижеприводимого, причем оно даже гибче, так как позволяет скопировать как весь файл пpи From и Count = 0, так и произвольный его кусок.