/* clip2.cpp   multiple clipboard formats example */

#include <windows.h>
#include "clip2.h"

int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine,
    int nCmdShow)
{
    HWND        hWnd ;      /* the window's "handle" */
    MSG         msg ;       /* a message structure */
    WNDCLASS    wndclass ;  /* window class structure */
    char        cBuf [128] ;

        wndclass.style          = CS_HREDRAW | CS_VREDRAW ;
        wndclass.lpfnWndProc    = WndProc ;
        wndclass.cbClsExtra     = 0 ;
        wndclass.cbWndExtra     = 0 ;
        wndclass.hInstance      = hInstance ;
        wndclass.hIcon          = NULL ;
        wndclass.hCursor        = LoadCursor (NULL, IDC_ARROW) ;
        wndclass.hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH) ;
        wndclass.lpszMenuName   = "MyMenu" ;
        wndclass.lpszClassName  = "MyClass" ;
                        /* register the window class */
        if (!RegisterClass (&wndclass))
            return 0 ;

    LoadString (hInstance, S_PROGRAMCAPTION, cBuf, sizeof (cBuf)) ;

    hWnd = CreateWindow ("MyClass", cBuf, WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
        NULL, NULL, hInstance, NULL) ;
    ShowWindow (hWnd, nCmdShow) ;   /* display the window */
    UpdateWindow (hWnd) ;

    while (GetMessage (&msg, NULL, 0, 0))   /* message loop */
    {
        TranslateMessage (&msg) ;   /* translate keyboard messages */
        DispatchMessage (&msg) ;    /* send message to WndProc() */
    }
    return (msg.wParam) ;
}

LRESULT CALLBACK WndProc (HWND hWnd, UINT wMessage, 
                                        WPARAM wParam, LPARAM lParam)
{
    HDC         hDC, hMemDC ;
    HINSTANCE   hInstance ;
    HANDLE      hGmem, hDigits, hClipMem  ;
    HBITMAP     hBitmap ;
    LPSTR       lpStr, lpClip ;
    int         i ;
    BITMAP      bm ;
    static WORD wClipFormat ;
    char        cBuf [128] ;

    switch (wMessage)       /* process windows messages */
    {
        case WM_COMMAND:
            switch (LOWORD(wParam))
            {
                case IDM_SENDCLIP:  /* copy 3 types of data to clipboard */
                                    /* allocate global memory block */
                    hGmem = GlobalAlloc (GHND, 32) ;
                    lpStr = (LPSTR)GlobalLock (hGmem) ;
                                    /* copy 26 letters to block */
                    for (i = 0 ; i < 26 ; i++)
                        *lpStr++ = (char)('A' + i) ;
                    GlobalUnlock (hGmem) ;

                        /* load a bitmap from resources into memory */
                        /* resulting handle can be sent to clipboard */ 
                    hInstance = (HINSTANCE)GetWindowLong (hWnd, GWL_HINSTANCE) ;
                    hBitmap = LoadBitmap (hInstance, "HOUSEBMP") ;

                                    /* register a new clipboard format */
                    wClipFormat = RegisterClipboardFormat ("DIGITS") ;
                                    /* send "DIGITS" data to clpbd */
                    hDigits = GlobalAlloc (GHND, 32) ;
                    lpStr = (LPSTR)GlobalLock (hDigits) ;
                                    /* copy digits to block */
                    lstrcpy (lpStr, "7774365") ;
                    GlobalUnlock (hDigits) ;

                                    /* send all three types of data */
                    if (OpenClipboard (hWnd))
                    {               /* in clipboard at the same time */
                        EmptyClipboard () ;
                        SetClipboardData (CF_TEXT, hGmem) ;
                        SetClipboardData (CF_BITMAP, hBitmap) ;
                        SetClipboardData (wClipFormat, hDigits) ;
                        CloseClipboard () ;
                    }
                    break ;

                case IDM_GETTEXT:     /* read the CF_TEXT clipboard data */
                    hDC = GetDC (hWnd) ;
                    if (OpenClipboard (hWnd))
                    {                 /* get handle to clipboard data */
                        hClipMem = GetClipboardData (CF_TEXT) ;
                        if (hClipMem) /* if there is CF_TEXT data... */
                        {             /* create 2nd block, sized for data */
                            hGmem = GlobalAlloc (GHND, GlobalSize (hClipMem)) ;
                            if (hGmem)
                            {           /* copy data from clipboard */
                                lpStr = (LPSTR)GlobalLock (hGmem) ;
                                lpClip = (LPSTR)GlobalLock (hClipMem) ;
                                lstrcpy (lpStr, lpClip) ;
                                TextOut (hDC, 0, 50, lpStr, lstrlen (lpStr)) ;
                                GlobalUnlock (hGmem) ;
                                GlobalUnlock (hClipMem) ;
                                GlobalFree (hGmem) ;
                            }
                        }
                        CloseClipboard () ;
                    }
                    ReleaseDC (hWnd, hDC) ;
                    break ;

                case IDM_GETBMP:  /* read & display bitmap from clipboard */
                    hDC = GetDC (hWnd) ;
                    if (OpenClipboard (hWnd))
                    {                   /* get handle to clipboard data */
                        hClipMem = GetClipboardData (CF_BITMAP) ;
                        if (hClipMem)   /* if there is CF_BITMAP data */
                        {
                            hMemDC = CreateCompatibleDC (hDC) ;
                            SelectObject (hMemDC, hClipMem) ;
                            GetObject (hClipMem, sizeof(BITMAP), (LPSTR)&bm) ;
                            BitBlt (hDC, 0, 0, bm.bmWidth, bm.bmHeight,
                                         hMemDC, 0, 0, SRCCOPY) ;
                            DeleteDC (hMemDC) ;
                        }
                        CloseClipboard () ;
                    }
                    ReleaseDC (hWnd, hDC) ;
                    break ;

                case IDM_GETSPECIAL:    /* get DIGITS clipboard data */
                    hDC = GetDC (hWnd) ;
                    if (OpenClipboard (hWnd))
                    {                   /* get handle to DIGITS data */
                        hClipMem = GetClipboardData (wClipFormat) ;
                        if (hClipMem)   /* if there is DIGITS data */
                        {
                            lpStr = (LPSTR)GlobalLock (hClipMem) ;
                            lstrcpy (cBuf, lpStr) ;
                            GlobalUnlock (hClipMem) ;
                            TextOut (hDC, 0, 70, cBuf, lstrlen (cBuf)) ;
                        }
                        CloseClipboard () ;
                    }
                    ReleaseDC (hWnd, hDC) ;
                    break ;
  
               case IDM_CLEAR:     /* clear the client area */
                    InvalidateRect (hWnd, NULL, TRUE) ;
                    break ;

                case IDM_QUIT:              /* Quit menu item */
                    DestroyWindow (hWnd) ;  /* destroy window, */
                    break ;     /* terminating application */
            }
            break ;

        case WM_DESTROY:    /* stop application */
            PostQuitMessage (0) ;
            break ;

        default:        /* default windows message processing */
            return (DefWindowProc (hWnd, wMessage, wParam, lParam)) ;
    }
    return (0) ;
}