2013-05-15 2 views
2

응용 프로그램을 작성했습니다. APP이라는 이름의 클래스가 있으며,이 창에는 핸들과 메시지 루프가 있으며이 모든 것들이 있습니다.여러 창을 클래스의 인스턴스로 사용하는 응용 프로그램

이 클래스의 일부 개체는 표준 창에 필요한 일련의 변수를 기반으로 자체 창으로 "실행"하기위한 것입니다.

메시지 루프는 공용으로 사용할 수 있으며 RunMessageLoop 메서드로 실행됩니다. int nCmdShow - 물론 창을 표시하는 방법을 알려주는 데 사용됩니다. 이제

, 내가 같은 일부 개체를 만들 때 :

vector <APP *> App; 
for (int i=0; i<3; i++) 
{ 
    App.push_back(&APP(nCmdShow)) 
    App[i]->RunMessageLoop(); 
} 

프로그램이 다른를 시작하기 전에 종료하는 각 메시지 루프를 기다립니다. 나는 실행 시작시 원하는 얼마나 많은 창 알게되면

vector <APP *> App; 
for (int i=0; i<3; i++) 
{ 
    App.push_back(&APP(nCmdShow)) 
} 
for (int i=0; i<3; i++) 
{ 
    App[i]->RunMessageLoop(); 
} 

, 괜찮을 것 같다 :

나는 이런 식으로 만들기 위해 알아 냈어.

하지만 다른 창과 완전히 독립적으로 새 창을 만드는 방법을 모르겠습니다. 메시지 루프를 호출하고 메시지 루프를 종료하지 않고 WinMain()으로 즉시 반환해야합니다.

나는 APP 클래스의 한 인스턴스 당 각 스레드, 멀티 스레드 응용 프로그램에 대해 생각. 하지만 멀티 스레드 응용 프로그램을 빌드하는 방법을 모르겠다.

가능한 해결책에 대한 아이디어가 있으십니까?

+1

코드에 정의되지 않은 동작이 있습니다. 'App.push_back (& ​​APP (nCmdShow))'하면 즉시 파기되는 임시 객체에 대한 포인터를 저장하고 있습니다. – juanchopanza

+0

글쎄, 창문을 볼 수 있고, 메시지에 반응하고 있기 때문에 파괴되지 않는다. 부적절하게 코드화 된 경우 가능한 경우 알려 주시기 바랍니다. – bercik

+1

@bercik "정의되지 않은 동작"은 작동하고있는 것처럼 보일 수 있으며 나중에 어떤 이유로 그 정의되지 않은 상태가 노출 될 때 몇 주가 지나야 만날 수 있습니다. 나는'& APP (nCmdShow)'가 컴파일되는 것에 놀랐다. 거기에'&'가 아닌'new'를 사용해야합니다. – molbdnilo

답변

0

_beginthreadex으로 실행해야하는 창 수와 같은 스레드를 생성하십시오. 그런 다음 스레드 프로 시저에서 메시지 루프를 실행하고 모든 스레드가 WaitForMultipleObjects으로 종료 될 때까지 기다립니다.

+0

응답 해 주셔서 감사합니다. 구현하고 결과를 얻으려고 노력할 것입니다. 그런 다음 피드백을드립니다. – bercik

0

내가 지금하고있는 것을보고, Lucid라는 애플리케이션 프레임 워크에서이 작업을 수행했습니다 (아직 진행중인 작업입니다). 대답을 위해 창 클래스는 APP 대신 Window이라고합니다.

작성하는 모든 창에 글로벌 프로 시저를 전달하면됩니다. 모든 창은이 동일한 절차를 공유합니다. 모든 창에 메시지가 도착할 때마다 해당 메시지가 전역 프로 시저로 전송되고 전역 프로 시저에서는 HWND이 사용자가 만든 Window에 속하는지 확인한 다음 Window의 절차에 메시지를 보냅니다. 이것이 어떻게 작동하는지에 대한 개요가 있습니다.

class Window 
{ 
public: 
    // The contents of this function can vary from window to window 
    // provided that you make a subclass and override this method. 
    virtual LRESULT procedure(HWND wnd, UINT msg, WPARAM wp, LPARAM lp); 

    // When you create a Window object, add a pointer to it in this map. 
    // Eg. if (this->hwnd != NULL) createdWindows[this->hwnd] = this; 
    static map<HWND, Window*> createdWindows; 

    // When you create a window, make this its procedure. 
    static LRESULT CALLBACK routeMessage(HWND wnd, UINT msg, WPARAM wp, LPARAM lp) 
    { 
     if (createdWindows.find(wnd) != createdWindows.end()) { 
      // Message belongs to one of our 'Window' objects. 
      // Pass the message to that window and return the result. 
      return createdWindows[wnd]->procedure(wnd, msg, wp, lp); 
     } else { 
      // It seems you made 'routeMessage' the procedure 
      // of a window that doesn't belong in the map. Go ahead 
      // and process the message in the default manner. 
      return DefWindowProc(wnd, msg, wp, lp); 
     } 
    } 
}; 

이제 단일 메시지 루프와 단일 스레드 만 있으면됩니다. 이게 도움이 되길 바란다. 그렇지 않으면 이벤트 처리기와 함께이 개념을 보여주는 Lucid 프로젝트에 대한 소스 코드를 제공 할 수 있습니다. 하나의 메시지 루프를 사용하여 단일 스레드에서 다른 절차로 2 개의 창을 만드는 Lucid를 사용하는 테스트 프로젝트가 있습니다.

#include "Lucid.h" 
using namespace Lucid; 

void sayBye(MessageEventArgs& e) 
{ 
    MessageBox(NULL, "Goodbye!", "Form 2", MB_OK); 
    e.handled = true; 
}  

void Program::onStart() 
{ 
    Form* myForm1 = new Form("Hello World!"); 
    myForm1->show(); 

    Form* myForm2 = new Form("Hello World!"); 
    myForm2->addMessageHandler(WM_CLOSE, sayBye); 
    myForm2->show(); 

    // This Program::onStart() function is called 
    // immediately before the single message loop is entered. 
} 
+0

감사합니다. 이것은 또한 매우 흥미 롭습니다. 나는 그것을 시도하고 그것에 대한 나의 생각을 게시 할 것이다. – bercik

관련 문제