#include<windows.h>
#include"resource.h"
#include"BMP_in.h"
#include"BMP_out.h"
#define IDM_FIRSTCHILD
0x00001000
#define MIN 0
#define RES 1
#define CLOSE 2
#define WM_ZoomMenu WM_APP+1
LRESULT
CALLBACK FrameWndProc(HWND,UINT,WPARAM,LPARAM);
LRESULT
CALLBACK DocProc(HWND,UINT,WPARAM,LPARAM);
BOOL
CALLBACK EnumChildProc(HWND,LPARAM);
int
MyRegisterWC(WNDPROC,LPCTSTR,HBRUSH);
char
szFrameClassName[]="frame";
char
szChildDoc[]="document";
HMENU
hMenuFirst,hMenuDoc;
HMENU
hMenuFirstWnd,hMenuDocWnd;
HINSTANCE
hInst;
int doc_no;
int WINAPI
WinMain(HINSTANCE hCurInst,HINSTANCE hPrevInst,
LPSTR lpsCmdLine,int nCmdShow)
{
MSG msg;
HWND hFrame,hClient;
hInst=hCurInst;
if(!MyRegisterWC(FrameWndProc,szFrameClassName,(HBRUSH)(COLOR_APPWORKSPACE+1)))
return FALSE;
if(!MyRegisterWC(DocProc,szChildDoc,(HBRUSH)GetStockObject(WHITE_BRUSH)))
return FALSE;
hMenuFirst=LoadMenu(hInst,"MYMENU");
hMenuFirstWnd=GetSubMenu(hMenuFirst,0);
hMenuDoc=LoadMenu(hInst,"MYDOCUMENT");
hMenuDocWnd=GetSubMenu(hMenuDoc,3);
hFrame=CreateWindow(
szFrameClassName,
"MDIζViewer",
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
hMenuFirst,
hInst,
NULL);
hClient=GetWindow(hFrame,GW_CHILD);
ShowWindow(hFrame,nCmdShow); ShowWindow(hFrame,SW_MAXIMIZE);
UpdateWindow(hFrame);
while
(GetMessage(&msg,NULL,0,0)){
if (!TranslateMDISysAccel(hClient,&msg)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
DestroyMenu(hMenuFirst);
DestroyMenu(hMenuDoc);
return (int)msg.wParam;
}
LRESULT
CALLBACK FrameWndProc(HWND hWnd,UINT msg,WPARAM wp,LPARAM lp)
{
static
HWND hClient;
HWND hChild;
CLIENTCREATESTRUCT ccs;
MDICREATESTRUCT mdic;
char
str[64],*str_org="hL
g No. = %d";
LPBMPINFO lpBmpInfo;
double dw;
HMENU
hMenu;
MENUITEMINFO
mi;
switch(msg){
case WM_CREATE:
ccs.hWindowMenu=hMenuFirstWnd;
ccs.idFirstChild=IDM_FIRSTCHILD;
hClient=CreateWindow(
"MDICLIENT",
NULL,
WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN,
0,0,0,0,
hWnd,
(HMENU)1,
hInst,
(LPVOID)&ccs);
return 0;
case WM_COMMAND:
switch(LOWORD(wp)){
case IDM_NEW:
doc_no++;
wsprintf(str,str_org,doc_no);
mdic.szClass=szChildDoc;
mdic.szTitle=str;
mdic.hOwner=hInst;
mdic.x=CW_USEDEFAULT;
mdic.y=CW_USEDEFAULT;
mdic.cx=CW_USEDEFAULT;
mdic.cy=CW_USEDEFAULT;
mdic.style=0;
mdic.lParam=0;
hChild=(HWND)SendMessage(hClient,WM_MDICREATE,0,(LPARAM)&mdic);
return 0;
case IDM_CLOSE:
hChild=(HWND)SendMessage(hClient,WM_MDIGETACTIVE,0,0);
if (hChild)
SendMessage(hClient,WM_MDIDESTROY,(WPARAM)hChild,0);
return 0;
case IDM_EXIT:
SendMessage(hWnd,WM_CLOSE,0,0);
return 0;
case IDM_CASCADE:
SendMessage(hClient,WM_MDICASCADE,0,0);
return 0;
case IDM_TILE:
SendMessage(hClient,WM_MDITILE,0,0);
return 0;
case IDM_HTILE:
SendMessage(hClient,WM_MDITILE,MDITILE_HORIZONTAL,0);
return 0;
case IDM_VTILE:
SendMessage(hClient,WM_MDITILE,MDITILE_VERTICAL,0);
return 0;
case IDM_ARRANGE:
SendMessage(hClient,WM_MDIICONARRANGE,0,0);
return 0;
case IDM_MINIMIZEALL:
EnumChildWindows(hClient,EnumChildProc,MIN);
return 0;
case IDM_RESTOREALL:
EnumChildWindows(hClient,EnumChildProc,RES);
return 0;
case IDM_CLOSEALL:
EnumChildWindows(hClient,EnumChildProc,CLOSE);
return 0;
case IDM_ZOOM1:
case IDM_ZOOM2: case IDM_ZOOM3:
case IDM_ZOOM4:
case
IDM_ZOOM02: case IDM_ZOOM03: case IDM_ZOOM04:
hChild=(HWND)SendMessage(hClient,WM_MDIGETACTIVE,0,0);
lpBmpInfo=(LPBMPINFO)GetWindowLong(hChild,GWL_USERDATA);
if(lpBmpInfo==NULL
|| lpBmpInfo->lpPixel==NULL) return 0;
switch(LOWORD(wp)){
case
IDM_ZOOM1:
lpBmpInfo->dw=1; lpBmpInfo->dh=1; break;
case
IDM_ZOOM2:
lpBmpInfo->dw=2; lpBmpInfo->dh=2; break;
case
IDM_ZOOM3:
lpBmpInfo->dw=3; lpBmpInfo->dh=3; break;
case
IDM_ZOOM4:
lpBmpInfo->dw=4; lpBmpInfo->dh=4; break;
case
IDM_ZOOM02: lpBmpInfo->dw=1.0/2; lpBmpInfo->dh=1.0/2; break;
case
IDM_ZOOM03: lpBmpInfo->dw=1.0/3; lpBmpInfo->dh=1.0/3; break;
case
IDM_ZOOM04: lpBmpInfo->dw=1.0/4; lpBmpInfo->dh=1.0/4; break;
}
InvalidateRect(hChild,NULL,TRUE);
return
0;
default:
hChild=(HWND)SendMessage(hClient,WM_MDIGETACTIVE,0,0);
if(IsWindow(hChild))
SendMessage(hChild,WM_COMMAND,wp,lp);
break;
}
break;
case WM_INITMENU:
hMenu=GetMenu(hWnd);
mi.cbSize=sizeof(MENUITEMINFO);
mi.fMask=MIIM_STATE;
hChild=(HWND)SendMessage(hClient,WM_MDIGETACTIVE,0,0);
lpBmpInfo=(LPBMPINFO)GetWindowLong(hChild,GWL_USERDATA);
if(lpBmpInfo!=NULL
&& lpBmpInfo->lpPixel!=NULL) mi.fState=MFS_ENABLED;
else
mi.fState=MFS_GRAYED;
SetMenuItemInfo(hMenu,IDM_COPY,FALSE,&mi);
if(IsClipboardFormatAvailable(CF_DIB))
mi.fState=MFS_ENABLED;
else mi.fState=MFS_GRAYED;
SetMenuItemInfo(hMenu,IDM_PASTE,FALSE,&mi);
if(lpBmpInfo!=NULL && lpBmpInfo->lpPixel!=NULL)
dw=lpBmpInfo->dw;
else
dw=0;
if(dw==1) mi.fState=MFS_CHECKED;
else mi.fState=MFS_UNCHECKED;
SetMenuItemInfo(hMenu,IDM_ZOOM1,FALSE,&mi);
if(dw==2) mi.fState=MFS_CHECKED;
else mi.fState=MFS_UNCHECKED;
SetMenuItemInfo(hMenu,IDM_ZOOM2,FALSE,&mi);
if(dw==3) mi.fState=MFS_CHECKED;
else mi.fState=MFS_UNCHECKED;
SetMenuItemInfo(hMenu,IDM_ZOOM3,FALSE,&mi);
if(dw==4) mi.fState=MFS_CHECKED;
else mi.fState=MFS_UNCHECKED;
SetMenuItemInfo(hMenu,IDM_ZOOM4,FALSE,&mi);
if(dw==1.0/2) mi.fState=MFS_CHECKED;
else mi.fState=MFS_UNCHECKED;
SetMenuItemInfo(hMenu,IDM_ZOOM02,FALSE,&mi);
if(dw==1.0/3) mi.fState=MFS_CHECKED;
else mi.fState=MFS_UNCHECKED;
SetMenuItemInfo(hMenu,IDM_ZOOM03,FALSE,&mi);
if(dw==1.0/4) mi.fState=MFS_CHECKED;
else mi.fState=MFS_UNCHECKED;
SetMenuItemInfo(hMenu,IDM_ZOOM04,FALSE,&mi);
DrawMenuBar(hWnd);
return 0;
case WM_QUERYENDSESSION:
case WM_CLOSE:
SendMessage(hWnd,WM_COMMAND,IDM_CLOSEALL,0);
if (GetWindow(hClient,GW_CHILD))
return 0;
break;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return
DefFrameProc(hWnd,hClient,msg,wp,lp);
}
LRESULT
CALLBACK DocProc(HWND hWnd,UINT msg,WPARAM wp,LPARAM lp)
{
static
HWND hClient,hFrame;
LPBMPINFO lpBmpInfo;
int iWidth,iHeight;
BITMAPINFO
biInfo;
LPDWORD
lpPixel;
double dw,dh;
HDROP
hDrop;
char szFileName[256];
HMENU
hMenu;
MENUITEMINFO
mi;
HDC hdc;
PAINTSTRUCT
ps;
switch(msg){
case WM_CREATE:
hClient=GetParent(hWnd);
hFrame=GetParent(hClient);
DragAcceptFiles(hWnd,TRUE);
lpBmpInfo=(LPBMPINFO)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(BMPINFO));
SetWindowLong(hWnd,GWL_USERDATA,(LONG)lpBmpInfo);
return 0;
case WM_DROPFILES:
hDrop=(HDROP)wp;
DragQueryFile(hDrop,0,szFileName,sizeof(szFileName));
DragFinish(hDrop);
if(!BMPfile_to_DIBSection(hWnd,szFileName)) return 0;
SendMessage(hWnd,WM_ZoomMenu,0,0);
InvalidateRect(hWnd,NULL,TRUE);
return 0;
case WM_COMMAND:
switch(LOWORD(wp)){
case
IDM_COPY:
CopyDIB(hWnd);
return
0;
case
IDM_PASTE:
if(!PasteDIBSection(hWnd)) return 0;
SendMessage(hWnd,WM_ZoomMenu,0,0);
InvalidateRect(hWnd,NULL,TRUE);
return
0;
}
break;
case WM_PAINT:
hdc=BeginPaint(hWnd,&ps);
lpBmpInfo=(LPBMPINFO)GetWindowLong(hWnd,GWL_USERDATA);
if(lpBmpInfo==NULL
|| lpBmpInfo->lpPixel==NULL){
EndPaint(hWnd,&ps);
return
0;
}
biInfo=lpBmpInfo->biInfo;
iWidth=biInfo.bmiHeader.biWidth;
iHeight=biInfo.bmiHeader.biHeight;
lpPixel=lpBmpInfo->lpPixel;
dw=lpBmpInfo->dw;
dh=lpBmpInfo->dh;
StretchDIBits(hdc,0,0,(int)(iWidth*dw),(int)(iHeight*dh),
0,0,iWidth,iHeight,lpPixel,&biInfo,
DIB_RGB_COLORS,SRCCOPY);
EndPaint(hWnd,&ps);
return 0;
case WM_MDIACTIVATE:
if(lp==(LPARAM)hWnd){
SendMessage(hClient,WM_MDISETMENU,(WPARAM)hMenuDoc,(LPARAM)hMenuDocWnd);
SendMessage(hWnd,WM_ZoomMenu,0,0);
}else{
SendMessage(hClient,WM_MDISETMENU,(WPARAM)hMenuFirst,(LPARAM)hMenuFirstWnd);
DrawMenuBar(hFrame);
}
return 0;
case
WM_ZoomMenu:
hMenu=GetMenu(hFrame);
mi.cbSize=sizeof(MENUITEMINFO);
mi.fMask=MIIM_STATE;
lpBmpInfo=(LPBMPINFO)GetWindowLong(hWnd,GWL_USERDATA);
if(lpBmpInfo!=NULL
&& lpBmpInfo->lpPixel!=NULL) mi.fState=MFS_ENABLED;
else
mi.fState=MFS_GRAYED;
SetMenuItemInfo(hMenu,2,TRUE,&mi);
DrawMenuBar(hFrame);
return
0;
case
WM_DESTROY:
DeleteDIBSection(hWnd);
break;
}
return
DefMDIChildProc(hWnd,msg,wp,lp);
}
BOOL
CALLBACK EnumChildProc(HWND hWnd,LPARAM lp)
{
switch(lp){
case MIN:
ShowWindow(hWnd,SW_MINIMIZE);
break;
case RES:
SendMessage(GetParent(hWnd),WM_MDIRESTORE,(WPARAM)hWnd,0);
break;
case CLOSE:
SendMessage(GetParent(hWnd),WM_MDIDESTROY,(WPARAM)hWnd,0);
break;
}
return TRUE;
}
int
MyRegisterWC(WNDPROC lpfnWndProc,LPCTSTR lpszClassName,HBRUSH hbrBack)
{
WNDCLASSEX wc;
wc.cbSize=sizeof(WNDCLASSEX);
wc.style=CS_HREDRAW |
CS_VREDRAW;
wc.lpfnWndProc=lpfnWndProc;
wc.cbClsExtra=0;
wc.cbWndExtra=0;
wc.hInstance=hInst;
wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);
wc.hCursor=LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground=hbrBack;
wc.lpszMenuName=NULL;
wc.lpszClassName=lpszClassName;
wc.hIconSm=LoadIcon(NULL,IDI_APPLICATION);
return
RegisterClassEx(&wc);
}