2014-09-23 9 views
0

외부 장치에서 데이터를로드하기위한 소형 앱을 제작 중입니다. 그것은 DLL을 사용합니다.UI의 올바른 디자인 패턴은 무엇입니까?

하나의 창에서 앱을 실행하고 싶습니다. 메뉴를 사용하여 올바른 UI 상태를 불러올 수 있어야합니다. 대화 상자 나 별도의 창을 사용하고 싶지 않습니다.

내 생각은 상태 변수를 사용하고 WM_PAINT 메시지가 다른 텍스트 (즉, 다른 텍스트와 버튼 항목에 대한 createwindowEx)를 처리하도록하는 것입니다.

올바른 방법입니까? 인터넷 검색, 프로그래밍 Windows 읽기 및 stackoverflow 검색 및 간단한 예제를 찾을 수 없습니다. 전용 winproc 기능을 사용하여 항상 다른 창을 사용합니다. 내가 그럴 필요가 없다고 느낀다. ...

누군가가 지시 나 작은 예/링크로 나를 도울 수 있습니까?

들으

편집 : 나는 내가 지금까지 지금 가지고있는 코드를 묶습니다. 누군가가 그것에 대해 살펴볼 수 있습니까, Thx. 제안 된 접근 방식으로

#if defined _MSC_VER || defined __BORLANDC__ 
#define OEMRESOURCE 
#endif 

#pragma comment(linker,"\"/manifestdependency:type='win32' \ 
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \ 
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") 

#include <windows.h> //include all the basics 
#include <tchar.h> //string and other mapping macros 
#include <iostream> 
#include <string> 
#include "hrmcom.h" 
#include "resource.h" 

typedef std::basic_string<TCHAR> ustring; 

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 
LRESULT CALLBACK ChildProc(HWND, UINT, WPARAM, LPARAM); 

inline int ErrMsg(const ustring&); 
bool CreateChild(HWND); 
bool CreateChildScreen(HWND); 

ustring classname = TEXT("MAINWND"); 
ustring childname = TEXT("CHILDWND"); 

HWND hwndChild[3], hwndCtrl[CTRNUM]; 

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR pStr, int nCmd) 
{ 
WNDCLASSEX wcx = { 0 }; 

wcx.cbSize = sizeof(WNDCLASSEX); 
wcx.lpfnWndProc = WndProc;    
wcx.hInstance = hInst; 
wcx.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_ICON1)); 
wcx.hCursor = reinterpret_cast<HCURSOR>(LoadImage(0, IDC_ARROW, 
    IMAGE_CURSOR, 0, 0, LR_SHARED)); 
wcx.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_BTNFACE + 1); 
wcx.lpszClassName = classname.c_str(); 

if (!RegisterClassEx(&wcx)) 
{ 
    ErrMsg(_T("Failed to register wnd class")); 
    return -1; 
} 
wcx.lpfnWndProc = ChildProc; 
wcx.cbWndExtra = sizeof (long); 
wcx.hIcon = NULL; 
wcx.lpszClassName = childname.c_str(); 

if (!RegisterClassEx(&wcx)) 
{ 
    ErrMsg(_T("Failed to register wnd class")); 
    return -1; 
} 

HMENU hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_MENU)); 

HWND hwnd = CreateWindowEx(0,      
    classname.c_str(),  
    TEXT("Polar Loader"),  
    WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU,  
    400, 200, 600, 300,  
    0,      
    hMenu,     
    hInst,     
    0);      
if (!hwnd) 
{ 
    ErrMsg(TEXT("Failed to create wnd")); 
    return -1; 
} 

ShowWindow(hwnd, nCmd); 
UpdateWindow(hwnd); 

MSG msg; 
while (GetMessage(&msg, 0, 0, 0)>0) 
{ 
    TranslateMessage(&msg); 
    DispatchMessage(&msg); 
} 
return static_cast<int>(msg.wParam); 
} 

LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 
{ 
switch (uMsg) 
{ 
case WM_CREATE: 
    //Create the Childwindows 
    if (!CreateChild(hwnd)) 
    { 
     ErrMsg(TEXT("Failed to create Childwindows")); 
     return -1; 
    } 
    //Create controls of the Childwindows 
    if (!CreateChildScreen(hwnd)) 
    { 
     ErrMsg(TEXT("Failed to create Conrols of Childwindows")); 
     return -1; 
    } 
    return 0; 
    case WM_COMMAND: 
    switch (LOWORD(wParam)) 
    { 
    case IDM_Acc: 
     ShowWindow(hwndChild[0], SW_SHOW); 
     return 0; 
    case IDM_Con: 
    case IDM_Help: 
    case IDM_Log: 
    case IDM_Pol: 
    case IDM_Trans: 
     ShowWindow(hwndChild[0], SW_HIDE); 
     return 0;  
    } 

case WM_DESTROY: 
    PostQuitMessage(0); //signal end of application 
    return 0; 
default: 
    //let system deal with msg 
    return DefWindowProc(hwnd, uMsg, wParam, lParam); 
} 
} 
LRESULT CALLBACK ChildProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 
{ 
switch (uMsg) 
{ 
case WM_CREATE: 
    SetWindowLong(hwnd, 0, 0);  
    return 0; 
case WM_COMMAND: 
    switch (LOWORD(wParam)) 
    { 
    case ID_CTRL+5:   
     MessageBeep(0); 
     return 0; 
    } 
default: 
    return DefWindowProc(hwnd, uMsg, wParam, lParam); 
} 
} 


inline int ErrMsg(const ustring& s) 
{ 
return MessageBox(0, s.c_str(), _T("ERROR"), MB_OK | MB_ICONEXCLAMATION); 
} 


bool CreateChild(HWND hwnd) 
{ 
static int x; 
for (x = 0; x < 3; x++) 
{ 
    hwndChild[x] = CreateWindowEx(0, childname.c_str(), NULL, 
     WS_CHILDWINDOW, 
     0, 0, 600, 300, 
     hwnd, (HMENU)x, 
     (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), 
     NULL); 
    if (!hwndChild[x]) return FALSE; 
} 
return TRUE; 
} 

bool CreateChildScreen(HWND hwnd) 
{ 
LPCWSTR lpType[CTRNUM] = { TEXT("static"), TEXT("edit"), TEXT("edit"), TEXT("static"), TEXT("static"), TEXT("button") }; 
LPCWSTR lpName[CTRNUM] = { TEXT("Log on to Gedysan Training App:"), TEXT(""), TEXT(""), TEXT("Username:"), TEXT("Password:"), TEXT("Log on") }; 
DWORD dStyle[CTRNUM] = { WS_CHILD | WS_VISIBLE | ES_LEFT, 
    WS_CHILD | WS_VISIBLE | ES_LEFT | WS_BORDER | ES_AUTOHSCROLL, 
    WS_CHILD | WS_VISIBLE | ES_LEFT | WS_BORDER | ES_PASSWORD | ES_AUTOHSCROLL, 
    WS_CHILD | WS_VISIBLE | ES_LEFT, 
    WS_CHILD | WS_VISIBLE | ES_LEFT, 
    WS_CHILD | WS_VISIBLE | ES_LEFT 
}; 
RECT rc[CTRNUM] = { { 15, 10, 400, 25 }, { 100, 40, 150, 25 }, { 100, 70, 150, 25 }, { 15, 45, 70, 25 }, { 15, 75, 70, 25 }, { 15, 110, 70, 25 } }; 
int iChildNum[CTRNUM] = { 0, 0, 0, 0, 0, 0 }; 
static int x; 
for (x = 0; x < CTRNUM; x++) 
{ 
    RECT x1 = rc[x]; 
    hwndCtrl[x] = CreateWindowEx(0, lpType[x], lpName[x], dStyle[x], 
     x1.left, x1.top, x1.right, x1.bottom, 
     hwndChild[iChildNum[0]], (HMENU)(ID_CTRL + x), 
     (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), 0); 
    if (!hwndChild[x]) return FALSE; 
} 
return TRUE; 
} 
+0

WM_PAINT가 CreateWindowEx의 올바른 위치가 아닙니다. 귀하의 질문에 대한 다른 부분은 명확하지 않습니다. 모든 프로그램 기능이 하나의 창을 사용하여 표시 될 수 있다면이를 수행 할 수 있습니다. –

+0

내 가난한 영어에 대한 나를 용서 ... 내가 의미하는 것은 선택한 메뉴를 기반으로 다른 UI를 제시해야한다는 것입니다. 예 : 계정 설정, 입력, 상태 보고서 등 모든 것을 하나의 창에 표시합니다. – gedysan

+0

이 경우 탭 컨트롤을 사용할 수 있습니다. 대화 상자 기반 Win32 응용 프로그램 만들기 : http://www.codeproject.com/Articles/227831/A-dialog-based-Win-C-program 그런 다음 대화 상자 템플릿에 탭 컨트롤을 추가하십시오. –

답변

2

당신은 지저분한 디자인을, 모든 WM_PAINT 핸들러에 관련이없는 물건을 잔뜩 얻을 것이다. 메뉴를 선택하면 메시지가 나타납니다. 메시지 핸들러에서 해당 메뉴 명령과 관련된 코드를 실행하십시오.

UI가 컨트롤로 구성된 경우 WM_PAINT는 전혀 관련되지 않습니다. 컨트롤은 자체 그림을 그립니다. WM_PAINT 핸들러는 필요한 커스텀 페인팅을 수행해야합니다.

+0

대답 Scott을위한 Thx. 제어 메시지에서 수행 할 수 있고 하위 창과 하위 창을 서로 바꿀 수 있습니까? 이 원리를 보여주는 예를 찾기가 어렵습니다. ... – gedysan

+0

예, 그것을하는 일반적인 방법입니다. 자식 창은 모덜리스 대화 상자입니다. 대화 상자처럼 보이지 않게하려면 제목 표시 줄 스타일을 끄고 시각적으로 기본 창에 표시됩니다. –

+0

나는 약간의 실험을했고 나는 그것을 작동 시키도록했다. 내가 끝내야 할 때, 나는 나의 버전으로 질문을 편집 할 것이다. 다행히 당신은 그것을 다음과 같이보고 싶습니다 :-). 주 창에 대해서는 windowsclass를, 네 명의 차일드에 대해서는 windowclass를 만들었습니다. 자식에게는 자체 winproc가 있습니다. 주요 winproc는 메뉴 메시지를 처리하고 자식 창을 표시하고 숨 깁니다. – gedysan

관련 문제