/////////////////////////////////////////////////////////////// // proto2.c - prototype Windows program for Project #2 // // ver 1.1 // // // // Language: Visual C, ver 6.0 // // Platform: Micron Dual Pentium Pro 200, Win NT 4.0 // // Application: CSE691 Project #1 // // Author: Jim Fawcett, Instructor, CSE691, Fall '99 // // CST 2-187, Syracuse Univ, (315) 443-3948 // // fawcett@ecs.syr.edu // // Sources: modified from head.c, Chap 8, // // Programming Windows 95, Charles Petzold, // // Microsoft Press, 1996 // /////////////////////////////////////////////////////////////// /* Module Operations: ================== This module is a prototype for project #2. It illustrates how to draw a triangle, how to fill it with a shade, and how to implement a menu. There is no public interface since no other software component calls functions in this module. /////////////////////////////////////////////////////////////// // build process // /////////////////////////////////////////////////////////////// // required files: // // pr2c.c // // // // building in IDE: // // - build project that includes this file // // - compile, line, and run // /////////////////////////////////////////////////////////////// Maintenance History: ==================== ver 1.1 : 29 Sep 99 - added version number - added manual page and maintenance page ver 1.0 : 22 Sep 99 - first release */ /* */ #include #include #include #include #include "resource.h" LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); typedef enum State { leftB, rightB } State; //----< entry point >------------------------------------------ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { HWND hwnd; // declare handle to window MSG msg; // declare message structure // build window class structure WNDCLASSEX wndclass; static char szAppName[] = "proto2"; wndclass.cbSize = sizeof (wndclass); wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); wndclass.hbrBackground = GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1); wndclass.lpszClassName = szAppName; wndclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION); // // register window class RegisterClassEx (&wndclass); // create main window at specified location with specified size hwnd = CreateWindow (szAppName, szAppName, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, 200, 200, 550, 200, NULL, NULL, hInstance, NULL); // display window ShowWindow (hwnd, iCmdShow); UpdateWindow (hwnd); // start message loop while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg); DispatchMessage (&msg); } return msg.wParam; } // //----< handle menu selections >------------------------------- // // - doesn't do anything except show user that a selection was detected // int handleMenu(HWND hwnd, WPARAM wParam) { HMENU hmenu; hmenu = GetMenu(hwnd); switch(LOWORD(wParam)) { case ID_FILEOPEN : MessageBox(hwnd, "file open selected", "test menu",MB_OK); return 0; case ID_FILEEXIT : PostQuitMessage(0); return 0; case ID_ROTATEAZIMUTH : MessageBox(hwnd, "rotate azimuth selected", "test menu",MB_OK); return 0; case ID_ROTATEELEVATION : MessageBox(hwnd, "rotate elevation selected", "test menu",MB_OK); return 0; case ID_TRANSLATE_XAXIS : MessageBox(hwnd, "translate x-axis selected", "test menu",MB_OK); return 0; case ID_TRANSLATE_YAXIS : MessageBox(hwnd, "translate y-axis selected", "test menu",MB_OK); return 0; case ID_TRANSLATE_ZAXIS : MessageBox(hwnd, "translate z-axis selected", "test menu",MB_OK); return 0; case 65535 : MessageBox(hwnd, "scale selected", "test menu",MB_OK); return 0; } return 0; } // //----< compute patch position and hue for display >----------- // // - compute vertices of a triangular patch relative to mouse position // - change hue so it oscillates between 0 (black) and 255 (white) // - invalidate entire window // void doPositionAndHue(HWND hwnd, POINT position, POINT patch[], int *pHue) { #define MinHue 0 #define MaxHue 255 static enum State { up, down } state; patch[0].x = position.x; patch[0].y = position.y; patch[1].x = patch[0].x + 30; patch[1].y = patch[0].y - 10; patch[2].x = patch[0].x - 10; patch[2].y = patch[0].y - 45; InvalidateRect(hwnd,NULL,TRUE); if(state == up) { *pHue += 25; if(*pHue > MaxHue) { *pHue = MaxHue; state = down; } } else { *pHue -= 25; if(*pHue < MinHue) { *pHue = MinHue; state = up; } } } //----< compute mouse display string >------------------------- // // - construct a display string showing mouse coordinates // - invalidate a small rectangle around the string // void doMouseDisplay(HWND hwnd, RECT smallRect, POINT position, char *staticText) { int size; staticText[0] = '['; itoa(position.x,&staticText[1],10); size = strlen(staticText); staticText[size] = ','; itoa(position.y,&staticText[size+1],10); size = strlen(staticText); staticText[size] = ']'; staticText[size+1] = '\0'; InvalidateRect(hwnd,&smallRect,TRUE); } // //----< handle paint message >--------------------------------- // // - display message about using mouse buttons in middle of window // changing grayscale to match hue // - display mouse coordinates at upper left of window // - draw triangular patch attached to current mouse coordinates // void doPaint( HWND hwnd, State state, int hue, char szText[], char staticText[], POINT patch[], RECT rect ) { PAINTSTRUCT ps; // structure to hold paint info HDC hdc; // handle to device context HBRUSH hb; // handle to brush used for filling closed regions hdc = BeginPaint (hwnd, &ps); SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)); // display message about mouse buttons in current hue SetTextColor (hdc, RGB(hue,hue,hue)); SetBkColor (hdc, RGB(255,255,255)); if(hue < 255) DrawText(hdc, szText, strlen(szText), &rect, DT_CENTER); // display mouse coordinates SetTextColor (hdc, RGB(0,0,0)); TextOut(hdc,10,10,staticText,strlen(staticText)); // draw triangular patch if(state == rightB) { // if right button don't fill SelectObject(hdc,GetStockObject(BLACK_PEN)); Polygon(hdc,patch,3); } else { // if left button fill to match current hue hb = CreateSolidBrush(RGB(hue,hue,hue)); SelectObject(hdc,hb); Polygon(hdc,patch,3); DeleteObject(hb); } EndPaint (hwnd, &ps); } // //----< process messages for main window >--------------------- LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { #define MAXWRITE 256 static RECT rect; // client area static RECT smallRect; // paint mouse coordinates here static char szText[MAXWRITE]; // buffer to hold output text static char staticText[MAXWRITE]; // buffer to hold label text static POINT position = {20,20}, patch[3]; static State state; static int hue = 0; switch (iMsg) { HDC hdc; // handle to device context TEXTMETRIC tm; // structure to hold font info case WM_CREATE : // define font and get text metrics for main window hdc = GetDC (hwnd); SelectObject (hdc, GetStockObject (DEFAULT_GUI_FONT)); GetTextMetrics (hdc, &tm); ReleaseDC (hwnd, hdc); // define writing area in main window GetClientRect(hwnd,&rect); // make rect have size of client area rect.top = 5 * tm.tmHeight; // change top to 5 lines down strcpy(szText,"press either left or right mouse button"); // define small region for fast updates to mouse coordinate display // -- do this so screen won't flicker smallRect.top = 10; smallRect.bottom = smallRect.top + 2*tm.tmHeight; smallRect.left = 10; smallRect.right = smallRect.left + 15*tm.tmAveCharWidth; return 0; case WM_COMMAND : return handleMenu(hwnd,wParam); case WM_SIZE : rect.right = LOWORD (lParam); rect.bottom = HIWORD (lParam); return 0; // case WM_LBUTTONDOWN : // define triangluar patch coordinates state = leftB; doPositionAndHue(hwnd,position,patch,&hue); return 0; case WM_RBUTTONDOWN : state = rightB; doPositionAndHue(hwnd,position,patch,&hue); return 0; case WM_MOUSEMOVE : position.x = LOWORD(lParam); position.y = HIWORD(lParam); doMouseDisplay(hwnd,smallRect,position,staticText); return 0; case WM_PAINT : doPaint(hwnd,state,hue,szText,staticText,patch,rect); return 0; case WM_DESTROY : PostQuitMessage (0); return 0; } return DefWindowProc (hwnd, iMsg, wParam, lParam); }