Конечно, можно упоминать модули только в части interface, но правильная расстановка имен модулей в соответствующем usesгарантирует исключение циклических ссылок, а также улучшает читаемость программы.
17. Как спрятать окна MDI Child?
Я пытаюсь это сделать, выставляя Form1.Visible := False , но это не помогает.
Windows не позволяет прятать окна MDI Child.
18. Как убрать заголовок у формы MDIChild?
Как убрать заголовок ( Caption ) из MDIChild?
Для MDIChild установка свойства BorderStyle := bsNone не убирает заголовок. Это можно сделать так:
procedureTMDIChildForm.CreateParams( varParams: TCreateParams);
begin
inheritedCreateParams(Params);
Params.Style := Params.Style and( notWS_CAPTION);
end;
19. Сохранение данных в Clipboard.
Мне нужно использовать clipboard для сохранения данных в собственном формате и я хочу для этого написать набор процедур ввода/вывода с использованием потоков (streams). Возможно ли создать объект TMemoryStream , эаполнить его и поместить в Clipboard?
Не только возможно, именно так поступают функции Clipboard.GetComponent и Clipboard.SetComponent . Сначала вы должны зарегистрировать свой собственный формат данных для Clipboard с помощью функции RegisterClipboardFormat :
CF_MYFORMAT := RegisterClipboardFormat('My Format Description'); Далее вы должны выполнить шаги:
1. Создать поток (memory stream) и записать туда данные.
2. Создать глобальный буфер в памяти и скопировать поток туда.
3. Вызвать Clipboard.SetAsHandle(), чтобы поместить буфер в Clipboard.
Пример:
var
hBuf: THandle;
Bufptr: Pointer;
MStream: TMemoryStream;
begin
MStream := TMemoryStream.Create;
try
{ write your data to the stream }
hBuf := GlobalAlloc(GMEM_MOVEABLE, MStream.Size);
try
BufPtr := GlobalLock(hBuf);
try
Move(MStream.Memory^, BufPtr^, MStream.Size);
Clipboard.SetAsHandle(CF_MYFORMAT, hBuf);
finally
GlobalUnlock(hBuf);
end;
except
GlobalFree(hBuf);
raise;
end;
finally
MStream.Free;
end;
end;
Внимание:не уничтожайте буфер, созданный с GlobalAlloc . Поскольку вы поместили его в Clipboard, это уже дело clipboard'а его уничтожить. Опять же, получая буфер из Clipboard, не уничтожайте этот буфер - просто сделайте копию содержимого.
Для обратного получения потока и данных, сделайте что-нибудь вроде этого:
var
hBuf: THandle;
BufPtr: Pointer;
MStream: TMemoryStream;
begin
hBuf := Clipboard.GetAsHandle(CF_MYFORMAT);
ifhBuf <> 0 then
begin
BufPtr := GlobalLock(hBuf);
ifBufPtr <> nil then
try
MStream := TMemoryStream.Create;
try
MStream.WriteBuffer(BufPtr^, GlobalSize(hBuf));
MStream.Position := 0;
{ read your data from the stream }
finally
MStream.Free;
end;
finally
GlobalUnlock(hBuf);
end;
end;
end;
20. Что означает Key<>#0 ?
В исходном тексте одного из компонентов третьих фирм я увидел строку:
ifKey <> #0 then inheritedKeyPress( #0);
В Windows виртуальные коды находятся в диапазоне 1-145 (Dec). Зачем нужна такая проверка?
В соответствии с соглашением Windows код клавиши #0означает отсутствие реального нажатия. Управление в данную точку программы могло попасть, например вследствие прямого вызова, а не нажатия клавиши или же нажатие уже было обработано предком, вследствие чего код нажатой клавиши был сброшен в 0.
21. Аналог процедуры TP/BP Delay.
procedureTForm1.Delay(MSecs: Longint);
var
FirstTick: Longint;
begin
FirstTick := GetTickCount;
repeat
Application.ProcessMessages;
untilGetTickCount - FirstTick >= MSecs;
end;
В Win32 API существуют также функции Sleep и SleepEx .
Читать дальше