과거에 간단한 PostMessage가 트릭을 수행했습니다. 은 기본적으로 당신은 기본 폼의 DoShow 중에 화재 :
procedure TBaseForm.DoShow;
begin
inherited;
PostMessage(Handle, APP_AFTERSHOW, 0, 0);
end;
다음 MSG를 잡아이 기본 폼에서 상속 된 모든 형태에 대한 AfterShow 이벤트를 만들 수 있습니다.
하지만 더 이상 작동하지 않습니다. 스키닝하고 많은 수의 VCL 컨트롤이있는 경우에는 좋지 않습니다.
내 다음 트릭은 DoShow에서 간단한 스레드를 생성하고 IsWindowVisible (Handle) 및 IsWindowEnabled (Handle)을 확인하는 것이 었습니다. DB 열기와 다른 것들은 이미 AfterShow 이벤트에 있었기 때문에로드 시간으로부터 250ms 가량 줄어 들었습니다.
그런 다음 마침내 madHooks를 생각해 보았습니다. API ShowWindow를 응용 프로그램에 연결하고 APP_AFTERSHOW를 실행하기에 충분했습니다.
function ShowWindowCB(hWnd: HWND; nCmdShow: Integer): BOOL; stdcall;
begin
Result := ShowWindowNext(hWnd, nCmdShow);
PostMessage(hWnd, APP_AFTERSHOW, 0, 0);
end;
procedure TBaseForm.Loaded;
begin
inherited;
if not Assigned(Application.MainForm) then // Must be Mainform it gets assigned after creation completes
HookAPI(user32, 'ShowWindow', @ShowWindowCB, @ShowWindowNext);
end;
는 모든 것이 완전히 여전히 ProcessPaintMessages 내 최종 테스트가 AfterShow 이벤트에 잠을 추가하고 완전히 빈 그린 양식을 볼 수
procedure TBaseForm.APPAFTERSHOW(var AMessage: TMessage);
begin
ProcessPaintMessages;
AfterShow;
end;
procedure ProcessPaintMessages; // << not tested, pulled out of code
var
msg: TMsg;
begin
while PeekMessage(msg, 0, WM_PAINT, WM_PAINT, PM_REMOVE) do
DispatchMessage(msg);
end;
이었다 전화를 필요 AfterShow 전에 페인트를 얻으려면 AfterShow 이벤트가 아직 완료되지 않았으므로 db 컨테이너.
procedure TMainForm.AfterShow;
begin
inherited;
Sleep(8*1000);
......
예를 들어 http://www.swissdelphicenter.com/torry/showcode.php?id=1276을 참조하십시오. 하지만 나는 Stack Overflow에 관한 질문이 있다고 확신한다. – TLama
메시지 게시 (제공된 링크와 마찬가지로) 특정 상황에서 메시지 (AFAIK)가 손실 될 수 있으므로 IMO는 완전히 신뢰할 수 없습니다. 200 % 신뢰할 수있는 무언가가 필요합니다. – user1580348
메시지가 손실되지 않습니다. 그러나'PostMessage'는 큐가 꽉 차면 큐에 넣을 수 없으며'PostMessage' 결과 매개 변수로 그 큐를 검색 할 수 있습니다. –