Win32 샘플 5 - 다중 윈도우/다중 뷰
앞의 예제인 단일 윈도우 다중 뷰를 확장하여 다중 윈도우를 여는 예를 보인다. 각 윈도우가 가지는 기능은 동일하며 메뉴의 "새 창 추가"를 실행하면 창이 하나 더 추가된다. 메모리의 전자해도 데이터 는 모든 창이 공유하기 때문에 창이 늘어난다고 해도 해도 데이터를 위한 메모리를 더 사용하지는 않는다.
보관된 원본 이미지가 없어 표시할 수 없습니다. 위 코드와 설명을 참고해 주십시오.
win32_sample05_01.png[그림 5-1] 다중 윈도우 어플리케이션의 새 창 열기 메뉴
보관된 원본 이미지가 없어 표시할 수 없습니다. 위 코드와 설명을 참고해 주십시오.
win32_sample05_02.png[그림 5-2] 새 창 열기의 결과로 생성된 윈도우
윈도우 맵
윈도우 정보나 윈도우 내의 뷰 정보를 다루는 클래스는 앞에서 살펴본 예제인 단일 윈도우/다중 뷰와 동일하며 윈도우 핸들을 키로 윈도우 정보를 밸류로 가지는 맵이 전역으로 선언되어 다수개의 윈도우에 대한 정보를 저장한다.
map<HWND, CWndInfo> g_wndInfo;
윈도우 개수 관리
생성된 창의 개수를 관리할 변수를 전역으로 설정한다. 생성될 각 창마다 동일한 변수가 동일한 값을 가지고 있게 된다.
int g_cntWindow = 0;
새 창 추가
메뉴의 커맨드를 처리하는 WM_COMMAND 메시지의 이벤트 핸들러에 해당되는 onCommand()에서 IDM_NEW_WINDOW 처리부에서 새 창을 다음과 같이 생성한다.
LRESULT onCommand(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
int wmId = LOWORD(wParam);
int wmEvent = HIWORD(wParam);
// 메뉴의 선택 영역을 구문 분석합니다.
switch (wmId) {
...
case IDM_NEW_WINDOW :
{
HWND hWnd = CreateWindow(
g_szWindowClass,
g_szTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
0,
CW_USEDEFAULT,
0,
NULL,
NULL,
g_hInstance,
NULL
);
ShowWindow(hWnd, SW_NORMAL );
UpdateWindow(hWnd);
}
break;
...
}
return 0;
}
창이 생성될 때의 처리
CreateWindow()에 의해 창이 생성될 때 WM_CREATE 메시지가 전달되는데 onCreate()에서 다음과 같이 새로운 창의 윈도우 핸들로 윈도우 맵의 아이템을 추가하고 그 아래에서 hencCreate()를 사용하여 새로 생성된 창에 대한 HGLRC를 생성한다.
LRESULT onCreate(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
TCHAR buf[256];
LPCREATESTRUCT cs = (LPCREATESTRUCT )lParam;
g_cntWindow++;
CWndInfo &info = g_wndInfo[ hWnd ];
info.m_hwnd = hWnd;
info.m_cntView = CNT_INITIAL_VIEW;
_stprintf_s( buf, 256, _T( "HNS ENC 0x%X" ), hWnd );
SetWindowText( hWnd, buf );
HDC hdc = GetDC( hWnd );
hencCreate( hWnd );
...
}
생성된 창의 제거
창을 닫을 때 WM_DESTROY 메시지가 전달되는 데 hencDelete() 함수를 사용하여 창과 연결된 HGLRC를 삭제하며 생성된 창의 개수 값이 0일 때는 PostQuitMessage() 함수를 실행하여 인스턴스를 종료한다.
LRESULT onDestory(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
hencDelete( hWnd );
if( --g_cntWindow <= 0 )
PostQuitMessage(0);
return 0;
}
WinMain.cpp
// SAMPLE.cpp : 응용 프로그램에 대한 진입점을 정의합니다.
//
#include "stdafx.h"
#define MAX_LOADSTRING 100
#define CNT_INITIAL_VIEW 1
// 전역 변수:
HINSTANCE g_hInstance; // 현재 인스턴스입니다.
TCHAR g_szTitle[MAX_LOADSTRING]; // 제목 표시줄 텍스트입니다.
TCHAR g_szWindowClass[MAX_LOADSTRING]; // 기본 창 클래스 이름입니다.
int g_cntWindow = 0;
map<HWND,CWndInfo> g_wndInfo;
void initComboSet( HWND hwnd, int id, const char *szSet[] ) {
HWND hwndCtrl = GetDlgItem( hwnd, id );
for( int i = 0; szSet[ i ] != NULL; i++ )
ComboBox_AddString( hwndCtrl, szSet[ i ] );
}
void viewRedrawAll() {
for_each(
g_wndInfo.begin(),
g_wndInfo.end(),
[]( pair<HWND,CWndInfo> wndinfo ) {
InvalidateRect( wndinfo.first, NULL, FALSE );
}
);
}
int setTopmost( HWND hwnd, int istop ) {
if( SetWindowPos( hwnd, istop ? HWND_TOPMOST : HWND_NOTOPMOST,
0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE ) )
return 0;
return -1;
}
void loadMap() {
hencLoad( _T( "SHP\\CNTRY92.SENC" ) );
CLoadENC loadEnc;
loadEnc.setMessage( EMI_CAPTION, _T( "Loading. . ." ) );
hencLoadFileListFromCatalogFile( _T( "SENC\\CATALOG.SENC" ), loadEnc.m_listFn );
dlgProgress( g_wndInfo.begin()->first, &loadEnc );
}
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow ) {
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
debugviewClearLog();
debugPrintf( __FUNCTION___T( "() START.\n" ) );
if( 0 > hencInit() ) {
MessageBox( GetDesktopWindow(), _T( "전자해도 커널을 초기화 할 수 없습니다." ), _T( "FATAL" ), MB_ICONERROR | MB_OK );
return -1;
}
g_hInstance = hInstance;
LoadString(hInstance, IDS_APP_TITLE, g_szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_SAMPLE, g_szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
if ( !InitInstance( hInstance, nCmdShow ) )
return FALSE;
loadMap();
viewRedrawAll();
{
HWND hwnd = g_wndInfo.begin()->first;
CWndMapView *mapview = &( g_wndInfo[ hwnd ].map( 0 ) );
if( mapview ) {
hencSelect( hwnd );
mapview->setViewport();
mapview->setMapParameter();
double mx, my, mx2, my2;
hencGetMapArea( mx, my, mx2, my2 );
hencSetMapArea( mx, my, mx2, my2 );
mapview->getMapParameter();
InvalidateRect( hwnd, NULL, FALSE );
}
}
HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_SAMPLE));
MSG msg;
while ( GetMessage( &msg, NULL, 0, 0 ) ) {
if ( TranslateAccelerator( msg.hwnd, hAccelTable, &msg ) )
continue;
TranslateMessage( &msg );
DispatchMessage( &msg );
}
hencDeinit();
debugPrintf( __FUNCTION___T( "() DONE.\n" ) );
return (int) msg.wParam;
}
void arrangeViews( CWndInfo &info ) {
//debugPrintf( __FUNCTION___T( "()\n" ) );
RECT r;
GetClientRect( info.m_hwnd, &r );
int w = r.right;
int h = r.bottom;
int row = 2;
int col = ( info.getViewCount() + row - 1 ) / row;
if( info.getViewCount() == 1 ) {
row = 1;
col = 1;
}
if( info.getViewCount() == 2 ) {
row = 1;
col = 2;
}
for( int i = 0; i < info.getViewCount(); i++ ) {
int wx = i % col * w / col;
int wy = i / col * h / row;
info.map( i ).m_viewx = wx;
info.map( i ).m_viewy = wy;
if( i == info.getViewCount() - 1 )
info.map( i ).m_vieww = w - info.map( i ).m_viewx;
else
info.map( i ).m_vieww = w / col;
info.map( i ).m_viewh = h / row;
}
}
ATOM MyRegisterClass(HINSTANCE hInstance) {
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_SAMPLE);
wcex.lpszClassName = g_szWindowClass;
wcex.hIconSm = LoadIcon( wcex.hInstance, MAKEINTRESOURCE( IDI_SAMPLE ) );
wcex.hIcon = LoadIcon( hInstance, MAKEINTRESOURCE( IDI_SAMPLE ) );
return RegisterClassEx(&wcex);
}
struct MONITOR_SELECT {
int found;
int m_monitorWant;
RECT m_rectMonitor;
HMONITOR m_monitor;
};
BOOL CALLBACK MonitorEnumProc( HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData ) {
MONITORINFO info;
info.cbSize = sizeof( info );
GetMonitorInfo( hMonitor, &info );
int num = 0;
if( info.dwFlags & MONITORINFOF_PRIMARY )
num = 0;
else
num = 1;
debugPrintf(
_T( "MONITOR=%d, %dx%d~%dx%d, %s\n" ),
hMonitor, lprcMonitor->left, lprcMonitor->top, lprcMonitor->right, lprcMonitor->bottom,
num ? _T( "Secondary" ) : _T( "Primary" )
);
MONITOR_SELECT *ms = (MONITOR_SELECT *)dwData;
if( num == ms->m_monitorWant ) {
ms->m_monitor = hMonitor;
ms->m_rectMonitor = *lprcMonitor;
ms->found = 1;
return FALSE;
}
return TRUE;
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) {
HWND hWnd;
g_hInstance = hInstance; // 인스턴스 핸들을 전역 변수에 저장합니다.
MONITOR_SELECT ms;
ms.m_monitorWant = 0;
ms.found = 0;
debugPrintf( _T( "g_monitor %d\n" ), ms.m_monitorWant );
EnumDisplayMonitors( NULL, NULL, MonitorEnumProc, (LPARAM )&ms );
int x = 0, y = 0, w = 0, h = 0;
if( ms.found ) {
x = ms.m_rectMonitor.left;
y = ms.m_rectMonitor.top;
w = ms.m_rectMonitor.right - ms.m_rectMonitor.left;
h = ms.m_rectMonitor.bottom - ms.m_rectMonitor.top - 40;
debugPrintf( _T( "monitor %d at %d,%d size=%d,%d\n" ), ms.m_monitorWant, x, y, w, h );
}
{
hWnd = CreateWindow(
g_szWindowClass,
g_szTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0,
CW_USEDEFAULT, 0,
NULL,
NULL,
hInstance,
NULL
);
if (!hWnd) {
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
//ShowWindow(hWnd, SW_MAXIMIZE );
UpdateWindow(hWnd);
}
return TRUE;
}
LRESULT onDestory(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
hencDelete( hWnd );
if( --g_cntWindow <= 0 )
PostQuitMessage(0);
return 0;
}
void drawOnGL( HWND hwnd, CWndMapView *map ) {
glEnable( GL_BLEND );
}
void drawOnDC( HWND hwnd, CWndMapView *map, HDC hdc ) {
int x = map->m_viewx;
int y = map->m_viewy;
int w = map->m_vieww;
int h = map->m_viewh;
{
CAutoSelectObject brush( hdc, GetStockObject( NULL_BRUSH ) );
CAutoSelectObject pen( hdc, CreatePen( PS_SOLID, 1, RGB(0,0,0) ) );
Rectangle( hdc, x, y, x + w, y + h );
}
}
void drawOnDCAll( HWND hWnd, HDC hdc ) {
CWndInfo &info = g_wndInfo[ hWnd ];
for( int i = 0; i < info.getViewCount(); i++ ) {
CWndMapView &map = info.map( i );
map.setViewport();
map.setMapParameter();
drawOnDC( hWnd, &map, hdc );
}
}
int glMapToDCAll( HWND hWnd, HDC hdc ) {
RECT r;
GetClientRect( hWnd, &r );
int w = r.right;
int h = r.bottom;
{
CAutoDeleteGdiObject bitmap( hencCaptureBuffer() );
{
CAutoBitmapDC hdcMem( bitmap );
drawOnDCAll( hWnd, hdcMem );
BitBlt( hdc, 0, 0, w, h, hdcMem, 0, 0, SRCCOPY );
}
}
//*////////////////////////////////////////////////////////////////////////////////////////////////
return 0;
}
int glMapToDC( HWND hWnd, HDC hdc, CWndMapView *map ) {
RECT r;
GetClientRect( hWnd, &r );
int w = r.right;
int h = r.bottom;
{
CAutoDeleteGdiObject bitmap( hencCaptureBuffer() );
{
CAutoBitmapDC hdcMem( bitmap );
drawOnDC( hWnd, map, hdcMem );
BitBlt(
hdc,
map->m_viewx,
map->m_viewy,
map->m_vieww,
map->m_viewh,
hdcMem,
map->m_viewx,
map->m_viewy,
SRCCOPY
);
}
}
//*////////////////////////////////////////////////////////////////////////////////////////////////
return 0;
}
int updateViewport( HWND hWnd, CWndMapView *map ) {
PFMCOUNTER_START( p );
hencSelect( hWnd );
map->setViewport();
map->setMapParameter();
hencClearViewport();
hencRender();
//debugPrintf( __FUNCTION___T( "() Viewport=%d,%d ~ %d, %d\n" ), map->m_viewx, map->m_viewy, map->m_vieww, map->m_viewh );
drawOnGL( hWnd, map );
HDC hdc = GetDC( hWnd );
glMapToDC( hWnd, hdc, map );
ReleaseDC( hWnd, hdc );
return 0;
}
LRESULT onPaint( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) {
PFMCOUNTER_START( p );
PAINTSTRUCT ps;
CWndInfo &info = g_wndInfo[ hWnd ];
HDC hdc = BeginPaint(hWnd, &ps);
//debugPrintf( _T( " hWnd=0x%x, HDC=0x%X\n" ), hWnd, hdc );
RECT r;
GetClientRect( hWnd, &r );
int w = r.right;
int h = r.bottom;
hencSelect( hWnd );
hencClearBackground();
for( int i = 0; i < info.getViewCount(); i++ ) {
CWndMapView &map = info.map( i );
map.setViewport();
map.setMapParameter();
PFMCOUNTER_START( r );
hencRender();
debugPrintf( _T( "hencRender()=%.3f\n" ), PFMCOUNTER_DIFF( r ) );
drawOnGL( hWnd, &map );
}
glMapToDCAll( hWnd, hdc );
EndPaint(hWnd, &ps);
return 0;
}
LRESULT onCommand(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
int wmId = LOWORD(wParam);
int wmEvent = HIWORD(wParam);
// 메뉴의 선택 영역을 구문 분석합니다.
switch (wmId) {
case IDM_MAKE_VIEW1 :
g_wndInfo[ hWnd ].m_cntView = 1;
arrangeViews( g_wndInfo[ hWnd ] );
InvalidateRect( hWnd, NULL, FALSE );
break;
case IDM_MAKE_VIEW4 :
g_wndInfo[ hWnd ].m_cntView = 4;
arrangeViews( g_wndInfo[ hWnd ] );
InvalidateRect( hWnd, NULL, FALSE );
break;
case IDM_MAXVIEW :
g_wndInfo[ hWnd ].m_cntView = MAX_VIEW;
arrangeViews( g_wndInfo[ hWnd ] );
InvalidateRect( hWnd, NULL, FALSE );
break;
case IDM_MORE_VIEW :
if( ++ g_wndInfo[ hWnd ].m_cntView >= MAX_VIEW )
g_wndInfo[ hWnd ].m_cntView = MAX_VIEW;
arrangeViews( g_wndInfo[ hWnd ] );
InvalidateRect( hWnd, NULL, FALSE );
break;
case IDM_LESS_VIEW :
if( -- g_wndInfo[ hWnd ].m_cntView < 1 )
g_wndInfo[ hWnd ].m_cntView = 1;
arrangeViews( g_wndInfo[ hWnd ] );
InvalidateRect( hWnd, NULL, FALSE );
break;
case IDM_NEW_WINDOW :
{
HWND hWnd = CreateWindow(
g_szWindowClass,
g_szTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
0,
CW_USEDEFAULT,
0,
NULL,
NULL,
g_hInstance,
NULL
);
ShowWindow(hWnd, SW_NORMAL );
UpdateWindow(hWnd);
}
break;
case IDM_ABOUT:
dlgAbout( hWnd );
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
LRESULT onSize(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
arrangeViews( g_wndInfo[ hWnd ] );
return 0;
}
LRESULT onCreate(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
TCHAR buf[256];
LPCREATESTRUCT cs = (LPCREATESTRUCT )lParam;
g_cntWindow++;
CWndInfo &info = g_wndInfo[ hWnd ];
info.m_hwnd = hWnd;
info.m_cntView = CNT_INITIAL_VIEW;
_stprintf_s( buf, 256, _T( "HNS ENC 0x%X" ), hWnd );
SetWindowText( hWnd, buf );
HDC hdc = GetDC( hWnd );
hencCreate( hWnd );
{
CWndMapView &map = info.map( 0 );
map.m_centerx = 0;
map.m_centery = 0;
map.m_zoom = 1;
map.m_degree = 0;
}
{
CWndMapView &map = info.map( 1 );
map.m_centerx = 126.411160;
map.m_centery = 37.369847;
map.m_zoom = 467.774752;
map.m_degree = 0;
}
{
CWndMapView &map = info.map( 2 );
map.m_centerx = 129.023807;
map.m_centery = 35.091644;
map.m_zoom = 7081.278033;
map.m_degree = 0;
}
{
CWndMapView &map = info.map( 3 );
map.m_centerx = 129.217037;
map.m_centery = 35.164078;
map.m_zoom = 753.355915;
map.m_degree = 0;
}
return 0;
}
CWndMapView *getMapViewOfPos( CWndInfo &info, int x, int y ) {
for( int i = 0; i < info.getViewCount(); i++ ) {
CWndMapView &map = info.map( i );
if( x >= map.m_viewx )
if( x < map.m_viewx + map.m_vieww )
if( y >= map.m_viewy )
if( y < map.m_viewy + map.m_viewh )
return &map ;
}
return NULL;
}
LRESULT CALLBACK onMbuttonDown(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
int x = GET_X_LPARAM( lParam );
int y = GET_Y_LPARAM( lParam );
//debugPrintf( _T( "WM_MBUTTONDOWN %d,%d\n" ), x, y );
CWndInfo &info = g_wndInfo[ hWnd ];
info.m_startx = info.m_mousex = x;
info.m_starty = info.m_mousey = y;
CWndMapView *mapview = getMapViewOfPos( info, x, y );
if( mapview == NULL )
return 0;
hencSelect( hWnd );
mapview->setViewport();
mapview->setMapParameter();
double dx = x;
double dy = y;
hencWinPosToMapPos( dx, dy );
updateViewport( hWnd, mapview );
return 0;
}
LRESULT CALLBACK onLbuttonDown(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
int x = GET_X_LPARAM( lParam );
int y = GET_Y_LPARAM( lParam );
//debugPrintf( _T( "WM_LBUTTONDOWN %d,%d\n" ), x, y );
CWndInfo &info = g_wndInfo[ hWnd ];
info.m_startx = info.m_mousex = x;
info.m_starty = info.m_mousey = y;
{
CWndMapView *mapview = getMapViewOfPos( info, x, y );
if( mapview == NULL )
return 0;
//debugPrintf( __FUNCTION___T( "() Viewport=%d,%d ~ %d, %d\n" ), mapview->m_viewx, mapview->m_viewy, mapview->m_vieww, mapview->m_viewh );
hencSelect( hWnd );
mapview->setViewport();
mapview->setMapParameter();
double dx = x;
double dy = y;
hencWinPosToMapPos( dx, dy );
//debugPrintf( _T( "WinPos %d,%d -> MapPos %f,%f\n" ), x, y, dx, dy );
mapview->m_centerx = dx;
mapview->m_centery = dy;
updateViewport( hWnd, mapview );
}
return 0;
}
LRESULT CALLBACK onLbuttonUp(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
int x = GET_X_LPARAM( lParam );
int y = GET_Y_LPARAM( lParam );
//debugPrintf( _T( "WM_LBUTTONUP %d,%d\n" ), x, y );
CWndInfo &info = g_wndInfo[ hWnd ];
info.m_mousex = x;
info.m_mousey = y;
return 0;
}
LRESULT CALLBACK onRbuttonDown(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
int x = GET_X_LPARAM( lParam );
int y = GET_Y_LPARAM( lParam );
//debugPrintf( _T( "WM_RBUTTONDOWN %d,%d\n" ), x, y );
CWndInfo &info = g_wndInfo[ hWnd ];
info.m_startx = info.m_mousex = x;
info.m_starty = info.m_mousey = y;
return 0;
}
LRESULT CALLBACK onLbuttonDoubleClick(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
int x = GET_X_LPARAM( lParam );
int y = GET_Y_LPARAM( lParam );
//debugPrintf( _T( "WM_LBUTTONDBLCLK %d,%d\n" ), x, y );
CWndInfo &info = g_wndInfo[ hWnd ];
info.m_mousex = x;
info.m_mousey = y;
CWndMapView *mapview = getMapViewOfPos( info, x, y );
if( mapview ) {
hencSelect( hWnd );
mapview->setViewport();
mapview->setMapParameter();
double mx, my, mx2, my2;
hencGetMapArea( mx, my, mx2, my2 );
hencSetMapArea( mx, my, mx2, my2 );
mapview->getMapParameter();
updateViewport( hWnd, mapview );
//InvalidateRect( hWnd, NULL, FALSE );
}
return 0;
}
LRESULT CALLBACK onRbuttonUp(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
int x = GET_X_LPARAM( lParam );
int y = GET_Y_LPARAM( lParam );
//debugPrintf( _T( "WM_RBUTTONUP %d,%d\n" ), x, y );
CWndInfo &info = g_wndInfo[ hWnd ];
info.m_mousex = x;
info.m_mousey = y;
CWndMapView *mapview = getMapViewOfPos( info, x, y );
if( mapview == NULL )
return 0;
if( x == info.m_startx )
if( y == info.m_starty ) {
//debugPrintf( _T( "--> Click Right\n" ) );
}
return 0;
}
LRESULT CALLBACK onRbuttonDoubleClick(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
int x = GET_X_LPARAM( lParam );
int y = GET_Y_LPARAM( lParam );
//debugPrintf( _T( "WM_RBUTTONDBLCLK %d,%d\n" ), x, y );
CWndInfo &info = g_wndInfo[ hWnd ];
info.m_mousex = x;
info.m_mousey = y;
CWndMapView *mapview = getMapViewOfPos( info, x, y );
if( mapview ) {
hencSelect( hWnd );
mapview->setViewport();
mapview->setMapParameter();
mapview->m_degree = 0;
updateViewport( hWnd, mapview );
//InvalidateRect( hWnd, NULL, FALSE );
}
return 0;
}
LRESULT CALLBACK onMouseWheel(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
int x = GET_X_LPARAM( lParam );
int y = GET_Y_LPARAM( lParam );
int zDelta = GET_WHEEL_DELTA_WPARAM(wParam);
POINT pt = { x, y };
ScreenToClient( hWnd, &pt );
x = pt.x;
y = pt.y;
//debugPrintf( _T( "WM_MOUSEWHEEL %d,%d delta=%d\n" ), x, y, zDelta );
CWndInfo &info = g_wndInfo[ hWnd ];
info.m_mousex = x;
info.m_mousey = y;
CWndMapView *mapview = getMapViewOfPos( info, x, y );
if( mapview ) {
if( wParam & MK_MBUTTON ) {
if( zDelta > 0 )
mapview->m_degree += 5;
else
mapview->m_degree -= 5;
}
else {
if( zDelta > 0 )
mapview->m_zoom *= 2.0;
else
mapview->m_zoom /= 2.0;
}
updateViewport( hWnd, mapview );
//InvalidateRect( hWnd, NULL, FALSE );
}
return 0;
}
LRESULT CALLBACK onMouseMove(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
int x = GET_X_LPARAM( lParam );
int y = GET_Y_LPARAM( lParam );
CWndInfo &info = g_wndInfo[ hWnd ];
int deltax = info.m_mousex - x;
info.m_mousex = x;
info.m_mousey = y;
CWndMapView *mapview = getMapViewOfPos( info, x, y );
if( mapview ) {
hencSelect( hWnd );
mapview->setViewport();
mapview->setMapParameter();
double dx = x;
double dy = y;
hencWinPosToMapPos( dx, dy );
if( MK_RBUTTON & wParam ) {
mapview->m_degree -= deltax;
updateViewport( hWnd, mapview );
//InvalidateRect( hWnd, NULL, FALSE );
}
}
return 0;
}
LRESULT CALLBACK onKeyDown(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
return 0;
}
LRESULT CALLBACK onTimer(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
InvalidateRect( hWnd, NULL, FALSE );
return 0;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch (message) {
case WM_TIMER :
return onTimer( hWnd, message, wParam, lParam );
case WM_KEYDOWN :
return onKeyDown( hWnd, message, wParam, lParam );
case WM_MBUTTONDOWN :
return onMbuttonDown( hWnd, message, wParam, lParam );
case WM_LBUTTONDOWN :
return onLbuttonDown( hWnd, message, wParam, lParam );
case WM_LBUTTONUP :
return onLbuttonUp( hWnd, message, wParam, lParam );
case WM_LBUTTONDBLCLK :
return onLbuttonDoubleClick( hWnd, message, wParam, lParam );
case WM_RBUTTONDOWN :
return onRbuttonDown( hWnd, message, wParam, lParam );
case WM_RBUTTONUP :
return onRbuttonUp( hWnd, message, wParam, lParam );
case WM_RBUTTONDBLCLK :
return onRbuttonDoubleClick( hWnd, message, wParam, lParam );
case WM_MOUSEWHEEL :
return onMouseWheel( hWnd, message, wParam, lParam );
case WM_MOUSEMOVE :
return onMouseMove( hWnd, message, wParam, lParam );
case WM_SIZE :
return onSize( hWnd, message, wParam, lParam );
case WM_CREATE :
return onCreate( hWnd, message, wParam, lParam );
case WM_COMMAND:
return onCommand( hWnd, message, wParam, lParam );
case WM_PAINT:
return onPaint( hWnd, message, wParam, lParam );
case WM_ERASEBKGND :
break;
case WM_DESTROY:
return onDestory( hWnd, message, wParam, lParam );
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}