2016-10-11 6 views
0

내 응용 프로그램은 InitInstance()에 비싼 물건을 만들어야합니다. 사용자에게 진행 상황을 알리고 싶습니다. 따라서 InitInstance() 메서드로 모덜리스 대화 상자를 만들기로했습니다.모덜리스 대화 상자에서 응용 프로그램 :: InitInstance()

내 문제는 대화 상자가 그려지지 않는다는 것입니다.

CStartStopDlg dlg(_T("Start")); 
dlg.Create(IDD_START_STOP_DLG); 
dlg.ShowWindow(SW_SHOW); 

// expensive stuff 

m_pMainWnd->ShowWindow(SW_SHOW); 
m_pMainWnd->UpdateWindow(); 

이 줄 이후에 잠자기를 설정하더라도 대화 상자가 업데이트됩니다. 문제는 MainFrame이 생성 된 리소스를 사용하므로이 줄을 재정렬 할 수 없다는 것입니다.

이 문제를 해결하는 방법은 무엇입니까?


편집 : 비싼 물건, 연결이 데이터베이스에 연결 및 작업자 스레드를 생성, 하드웨어를 io를하기 위해 카메라에 연결입니다. 응용 프로그램 개체는이 모든 것들을 소유하고 있으며 메인 프레임과 그보기 등이 이것을 사용합니다. 이 물건은 응용 프로그램과 관련된 문서가 아니기 때문에.

이더넷로드에 따라 연결하는 데 다른 시간이 걸립니다.

모달 대화 상자는 반응 할 필요가 없습니다. 난 그냥 어도비 리더의 시작 대화 같은 것을 원한다.

UpdateWindow() 힌트는 올바른 방향이었고 상태를 업데이트 할 때이 함수에 대한 호출을 추가했습니다. 이게 내 문제를 해결했습니다.

+0

대화 상자를 그리려면 응용 프로그램이 산출해야합니다. dlg.UpdateWindow() 또는 what을 호출하더라도 대화 상자는 "값 비싼 물건"을 수행하는 동안 사용자 입력에 응답하지 않습니다. 대화 상자를 다른 스레드에 만들 수 있습니까? 또 다른 구현은 앱이 초기화 된 후에 예약 된 다른 스레드 (예 : 타이머 사용)에서 '값 비싼 물건'을 대신 실행하는 것입니다. "비싼 물건"이 완료 될 때까지 UI 요소를 사용 중지해야합니다. –

답변

2

"값 비싼 물건"은 계산 된 것이고 UI 스레드의 업데이트를 허용하지 않는 것 같습니다. 이러한 유형의 문제는 일반적으로 별도의 스레드를 사용하여 진행률 피드백을 제공함으로써 해결됩니다. 이러한 유형의 문제를 해결하기 위해 스레드를 사용하는 것에 대한 배경은 Using Worker Threads을 참조하십시오. pParentWnd 암시 적 (CDialog::CDialog 참조) NULL로 설정되어 있기 때문에

+0

* "값 비싼 물건이 계산 된 것 같습니다"* - 질문의 아무 것도 이것을 나타내지 않으며, 그렇다고해도 어쨌든 관계가 없습니다. 중요한 세부 사항은 ** 동기 **입니다. 통찰력의 부족을 덮기 위해 유행어에 대해 던지기는 여기를 돌아 다니지 않을 것입니다, 나는 두려워합니다. 제안 된 답변의 나머지 부분은 매우 희박하여 "이 답변은 유용하지 않습니다"* 투표에 부칠 자격이 있습니다. – IInspectable

+0

@IInspectable 나는 당신의 의견을 존중할 수 있지만, 나는 종종이 사이트의 많은 사람들에게 당신이 어떻게 반응하는지 놀라게됩니다. 적어도 한 사람이 내 대답을 도움이되는 것으로 보았지만 나에 대한 첫 번째 사실을 모른 채 나를 모욕하려고합니다. 거울을 들여다가 그 불쾌한 행진이 어디에서 왔는지보아야 할 때입니다. – rrirower

+0

나도 몰라, 왜 너는 이것을 개인적인 차원에서 받아들이 겠느냐. 나는 답의 품질에 대해 논평했다. (그리고 당신은 ** 단정 한 ** vote를 버릴 수있다. 이것은 일반적으로 OP가 * "Thanks"*라고 말하는 방법이지만 품질의 지표로는 사용하지 않는다.). 이 제안 된 대답은 잘못된 가정으로 시작하고 해결책을 제안하려고 시도합니다 (우연에 의해 적용되는 경우에만 발생합니다). 당신이 놀랐다면 나는 왜 제안 된 응답에 대해 의견을 남기고, 당신이 원하는 모든 것을 놀라게 할 것입니다. 그래도 나는 당신을 위해 예외를 만들 수 있습니다. – IInspectable

3

CStartStopDlg dlg(_T("Start"));owned 대화 상자를 만듭니다. 이 대화 상자는 주 응용 프로그램 창에서 소유합니다.

소유 된 창의 한 기능은 소유자가 숨겨져있을 때 숨겨져 있다는 것입니다. 따라서 m_pMainWnd->ShowWindow(SW_SHOW);에 전화 할 때까지 소유 한 대화 상자가 나타나지 않습니다.

이 문제를 해결하는 방법에는 여러 가지가 있습니다.

  1. 명백한 해결책은 주 응용 프로그램 창을 즉시 표시하는 것입니다. 그러나 이것은 실용적이지 않을 수도 있습니다 (UI 스레드 차단과 관련된 문제를 해결하지 못함).
  2. 작업자 스레드에 값 비싼 초기화 오프로드 :
    이것은 UI 스레드가 들어오는 메시지를 처리 ​​할 수 ​​있도록하기 위해 필요합니다. 사용자 상호 작용의 결과로 작업자 스레드와 GUI 스레드간에 일종의 통신을 구현해야합니다. 일반적으로 주 응용 프로그램 창에 사용자 지정 메시지 (WM_APP + x)를 게시하는 것으로 충분합니다.
  3. 값 비싼 초기화를 연기하십시오.
    InitInstance은 응용 프로그램의이 인스턴스를 시작하는 데 필요하지 않습니다. 어떤 종류의 값 비싼 작업도 사용자가 UI를 볼 수있는 지점까지 연기해야합니다 (잠재적으로 해당 작업을 취소 할 수 있음).
    일반적인 접근 방법은이를위한 원샷 타이머를 만드는 것입니다. WM_TIMER 메시지의 우선 순위가 낮기 때문에 메시지는 다른 모든 메시지가 처리 된 후에 만 ​​도착하고 응용 프로그램은 작동 가능 상태에 있습니다. 이 시점에서 값 비싼 초기화를 작업자 스레드로 오프로드하고 완료 될 때까지 모달 대화 상자를 표시 할 수 있습니다.
관련 문제