|
이놈의 건망증이.. 하늘을 찌르는군요.. 에휴..
Form의 Visible 을 검사해서 아직 나오지 않은 폼이면 처리를 건너 뛰어야 하는뎅.. 안그러면 FormCreate시에.. 하루 종일 맴돌거든요.. 그리고 SetWindowPos에서 먹통이 되는 이유는.. 메세지가 SetWindowPos시에 다시 발생되는데, 그 다시 발생되는 메세지는 건너 뛰에 만들어주어야 하기 때문입니다.
void __fastcall TForm2::SetFormOnTop(TMessage &msg)
{
int itCount;
TForm *fmTemp;
if(!Form2 || !Form2->Visible || Form2->Tag) return;
for(itCount = 0; itCount < Application->ComponentCount; itCount ++) {
fmTemp = dynamic_cast<TForm *>(Application->Components[itCount]);
if(fmTemp && fmTemp->FormStyle == fsStayOnTop)
fmTemp->Tag = 1;
}
SetWindowPos(Form2->Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
for(itCount = 0; itCount < Application->ComponentCount; itCount ++) {
fmTemp = dynamic_cast<TForm *>(Application->Components[itCount]);
if(fmTemp && fmTemp->FormStyle == fsStayOnTop)
fmTemp->Tag = 0;
}
}
이런식으로 처리를 해보았구요.. 그냥 간단하게 Tag를 이용해서.. 한거예요.. Tag 를 이용하시는것이 맘에 안드시면 각각의 public 함수에서 아무거나 지정하셔서 하시면 되겠지요? ^^;
위처럼 Form 전체의 Tag를 막는것은.. 두개 이상의 폼의 StayOnTop의 처리를 위한것이고요.. 첨부 파일에서는 Form1, Form2를 모두 StayOnTop을 시킵니다.
프로젝트 파일 첨부시켜 놓았습니다.
하느리 님이 쓰신 글 :
: 저도 처음에 SetWindowPos를 이용하여 처리하여 보려고 했는데, 이상한 것은 WINDOWPOSCHANGING 메세지 처리 함수 내에서 이 함수를 이용하면 시스템이 먹통이 되더군요(운영체제 : Windows Me). 지금의 방법으로 하여도 마찬가지이고요.
:
: 죄송한데, 테스트 해 보신 프로그램 소스를 좀 올려 주실 수 있으시겠어요 ? 제가 무엇이 잘못되어 그러는지 확인 좀 해 볼려구요.
:
:
:
:
: 유영인.Chris 님이 쓰신 글 :
: : void __fastcall TForm2::SetFormOnTop (TMessage &msg)
: :
: : 이 함수 안에서..
: :
: : LPWINDOWPOS lpwp = (LPWINDOWPOS) (msg.LParam);
: : lpwp->hwndInsertAfter = NULL; // 내 앞에는 아무도 없어 !
: :
: : 이것 대신에...
: :
: : SetWindowPos(Form1->Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
: :
: : 이걸 한번 넣어보시는것은 어떠세요..? Focus 를 가져간다는 단점이 있지만요.. 긁적..
: :
: : 그리고.. SetWindowPos를 하시면, Message가 다시 발생하므로, 중복발생을 막기 위해서.. 아래와 같이 메세지 처리를 무시하는 부분도 필요하겠죠.
: :
: : void __fastcall TForm2::SetFormOnTop (TMessage &msg)
: : {
: :
: : if(!Form2->ProcessMessaging) {
: : Form2->ProcessMessaging = true;
: : SetWindowPos(Form2->Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
: : Form2->ProcessMessaging = false;
: : }
: :
: : }
: :
: :
: : Application->OnMessage 으로 간단하게 처리해볼려고 애썼는데.. 시간만 뺏기구.. 왜 WM_WINDOWPOSCHANGING 이 메세지는 그 핸들러로 뜨지 않는지 모르겠네요.
: :
: : ProcessMessaging 는 그냥 변수 입니다. 임의로 지정된것이고요, 귀찮으시면 Tag 프로퍼티를 이용하셔도 됩니다. 만약, Form1 도 함께 처리해 주실려면, SetWindowPos 에서 Form1의 메세지도 함께 발생시키니..
: :
: : Form1->ProcessMessaging = true;
: : Form2->ProcessMessaging = true;
: :
: : SetWindowPos(Form2->Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
: :
: : Form1->ProcessMessaging = false;
: : Form2->ProcessMessaging = false;
: :
: : 이런식으로 막아 주셔야 합니다. 폼이 많아지면, Application에서 ComponentConut로 쭉 돌다가.. StayOnTop 으로 설정되어 있는 모든 폼을 처리해 주시면 되겠지요. (이 부분 소스가 필요하시면 따로 첨부하겠습니다)
: :
: : 어쨌든.. 저렇게 하시면 됩니다.. 잘 되는거 확인까지 했어요.. -_-a
: :
: :
: :
: : 하느리 님이 쓰신 글 :
: : : 유영인님이 가르쳐 주신 방법으로 처리해 보았으나, 정상적으로 최상위 윈도우가 되지를 않네요. 될 때가 있고, 않될 때가 있네요. 처리한 방법은 폼에 이벤트를 추가하여 처리하였습니다. 혹 제가 잘못 처리한 것인지 몰라 테스트했던 소스를 올립니다.
: : : void __fastcall TForm2::SetFormOnTop (TMessage &msg)
: : : {
: : : LPWINDOWPOS lpwp = (LPWINDOWPOS) (msg.LParam);
: : : lpwp->hwndInsertAfter = NULL; // 내 앞에는 아무도 없어 !
: : :
: : : }
: : : 여러가지를 테스트해 보았는데, 위에 있는 hwndInsertAfter 이외에는 별다른 효과가 없더군요. flags에 이것저것 설정을 해 보았는데, 소용 없었습니다. 위와 같이 설정한 상태에서 빌더상에서 디버깅모드로 실행을 해 보면, 빌더의 소스영역을 클릭하는 것으로부터는 최상위 윈도우가 유지가 되나, 소스윈도우의 타이틀바를 누르면 최상위윈도우에서 뒤로 밀려 나더군요.
: : :
: : :
: : : 한번 확인해 봐 주시겠습니까 ?
: : :
|