#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="ƒhƒLƒ…ƒƒ“ƒ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);

}