main.c

来自「allows the user to select files containi」· C语言 代码 · 共 430 行

C
430
字号
#define STRICT
#include <windows.h>
#include <windowsx.h>
#include <commdlg.h>
#include <assert.h>
#include <string.h>
#include <stdio.h>

#include "resource.h"
#include "object.h"
#include "draw.h"


#define START 10

/*** Local variables to the module ***/
static POBJECT_3D pObject = NULL;   /* Current Object */
static double dDistance;            /* Distance used in the perspective view */
static double dA;                   /* A Angle used in Axonometric view */ 
static double dB;                   /* B Angle used in Axonometric view */ 
static double dFactor;              /* Reduce factor in oblique view */
static double dAngle;               /* Angle used in Oblique view */     
static int iParamOpt = 0;           /* Current parameter */
static int iOffset;                 /* Starting offset used in the project window */

/*** Function prototypes ***/
static BOOL Proj_OnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct);
static void Proj_OnSize(HWND hWnd, UINT state, int cx, int cy);
static void Proj_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify);
static void Proj_OnChar(HWND hWnd, TCHAR ch, int cRepeat);
static void Proj_OnPaint(HWND hWnd);
static void Proj_OnDestroy (HWND hwnd);

static BOOL GetFileName (HWND hWnd, char *pszFileName, int cMaxString);
static void ChangeMenuOptions (HWND hWnd, int iOldOpt, int iNewOpt, int iMenu);
static void DisableMenuOptions (HWND hWnd, int iMenu);
static void EnableMenuOptions (HWND hWnd, int iMenu);

static BOOL ModifyVar (double *pdValue, double dFactor, double dMin, double dMax, BOOL bOp);
static void ProcessOption (HWND hWnd, int iOption );

/*
 * Main window message handling function.
 */

LRESULT CALLBACK Proj_WndProc(HWND hWnd, UINT uMsg,WPARAM wParam, LPARAM lParam)
{
  switch(uMsg) {
    HANDLE_MSG (hWnd, WM_CREATE, Proj_OnCreate);

    HANDLE_MSG (hWnd, WM_SIZE, Proj_OnSize);

    HANDLE_MSG (hWnd, WM_COMMAND, Proj_OnCommand);

    HANDLE_MSG (hWnd, WM_CHAR, Proj_OnChar);

    HANDLE_MSG (hWnd, WM_PAINT, Proj_OnPaint);

    HANDLE_MSG (hWnd, WM_DESTROY, Proj_OnDestroy);

    default:
      return DefWindowProc(hWnd,uMsg,wParam,lParam);
  }
}

/*** Private Functions ***/

/*
 * Process the criation message
 */
static BOOL Proj_OnCreate(HWND hWnd, LPCREATESTRUCT lpCreateStruct)
{
  MATRIX_4x4 matrix;

  MatrixFront (matrix);
  DrawSetProjection (matrix);
  
  return TRUE;
}

/*
 * Updates the window size
 */
static void Proj_OnSize(HWND hWnd, UINT state, int cx, int cy)
{
  RECT window, viewport;

  window.left = -1;
  window.right = 1;
  window.top = 1;
  window.bottom = -1;

  viewport.left = START;
  viewport.top = START;

  if (cx < cy) {
    viewport.right = cx - START;
    viewport.bottom = cx - START;
    iOffset = cx - START;
  }
  else {
    viewport.right = cy - START;
    viewport.bottom = cy - START;
    iOffset = cy - START;
  } 

  DrawSetTransformation (&window, &viewport);
}

/*
 * Processes the mensages WM_COMMAND.
 */
static void Proj_OnCommand(HWND hWnd, int id, HWND hwndCtl, UINT codeNotify)
{
  static char szFileName [_MAX_PATH];
  
  switch (id) {
    case IDM_OPEN : if (GetFileName (hWnd, szFileName, _MAX_PATH - 1)) {
                      if (pObject != NULL) {
                        ObjectFree (pObject);
                        pObject = NULL;
                      }

                      pObject = ObjectLoad (szFileName);
                      if (pObject == NULL)
                        MessageBox (hWnd, "Error while loading file", "Proj",
                                    MB_OK | MB_ICONSTOP);
                      else {
                        EnableMenuOptions (hWnd, 1);
                        FORWARD_WM_COMMAND (hWnd, IDM_MAIN, NULL, NULL, SendMessage);
                      }
                    }
                    break;
    case IDM_MAIN :
    case IDM_SIDE:
    case IDM_TOP  :
    case IDM_OBLIQUE :
    case IDM_PERSPECTIVE : 
    case IDM_AXONOMETRIC : 
                    ProcessOption (hWnd, id);
                    break;


    case IDM_A_FACTOR : 
                    ChangeMenuOptions (hWnd, iParamOpt, id, 2);
                    iParamOpt = id;
                    break;



    case IDM_B_FACTOR : 
                    ChangeMenuOptions (hWnd, iParamOpt, id, 2);
                    iParamOpt = id;
                    break;


    case IDM_REDUCE_FACTOR : 
                    ChangeMenuOptions (hWnd, iParamOpt, id, 2);
                    iParamOpt = id;
                    break;

    case IDM_ANGLE : 
                    ChangeMenuOptions (hWnd, iParamOpt, id, 2);
                    iParamOpt = id;
                    break;


    case IDM_EXIT : PostMessage (hWnd, WM_CLOSE, 0, 0);
                    break;
  }
}


/*
 * Processes the keyboard messages.
 */
static void Proj_OnChar(HWND hWnd, TCHAR ch, int cRepeat)
{
  if (ch == '-' || ch == '+') {
    BOOL bChanged;
    BOOL bOp = (ch == '+');
    MATRIX_4x4 matrix;

    switch (iParamOpt) {
      case IDM_PERSPECTIVE : bChanged = ModifyVar (&dDistance, 0.1, 1, 100, bOp);
                             if (bChanged)
                               MatrixPerspective (matrix, dDistance);
                             break;


      case IDM_A_FACTOR :  bChanged = ModifyVar (&dA, 1, 1, 89.9, bOp);
                           if (bChanged)
                             MatrixAxonometric (matrix, dA, dB);
                           break;

      case IDM_B_FACTOR :  bChanged = ModifyVar (&dB, 1, 1, 89.9, bOp);
                           if (bChanged)
                            MatrixAxonometric (matrix, dA, dB);
                           break;


      case IDM_REDUCE_FACTOR :  bChanged = ModifyVar (&dFactor, 0.1, 0, 100, bOp);
                           if (bChanged)
                            MatrixOblique (matrix, dFactor, dAngle);
                           break;


      case IDM_ANGLE :     bChanged = ModifyVar (&dAngle, 0.1, 1, 90, bOp);
                           if (bChanged)
                            MatrixOblique (matrix, dFactor, dAngle);
                           break;


      default: MessageBeep (0);
               return; 
    }
   
    if (bChanged) {
      DrawSetProjection (matrix);
      InvalidateRect (hWnd, NULL, TRUE);
      UpdateWindow (hWnd);
    }
  }
}
/*
 * Processes the paint messages.
 */
static void Proj_OnPaint(HWND hWnd)
{
  PAINTSTRUCT ps;
  HDC hDC;
  char szMsg [1024];

  hDC = BeginPaint (hWnd, &ps);

  if (pObject != NULL) {
    Rectangle (hDC, START, START, iOffset, iOffset);
    switch (iParamOpt) {
      case IDM_PERSPECTIVE : sprintf (szMsg, "Distance : %g", dDistance);
                             TextOut (hDC, iOffset + 10, 10, szMsg, strlen (szMsg));
                             break;
      case IDM_A_FACTOR :  
      case IDM_B_FACTOR :  sprintf (szMsg, "Angle A : %g degrees", dA);
                           TextOut (hDC, iOffset + 10, 10, szMsg, strlen (szMsg));
                           sprintf (szMsg, "Angle B : %g degrees", dB);
                           TextOut (hDC, iOffset + 10, 30, szMsg, strlen (szMsg));
                           break;

      case IDM_REDUCE_FACTOR :
      case IDM_ANGLE :     sprintf (szMsg, "Reduce Factor : %g ", dFactor);
                           TextOut (hDC, iOffset + 10, 10, szMsg, strlen (szMsg));
                           sprintf (szMsg, "Escape Angle : %g degrees", dAngle);
                           TextOut (hDC, iOffset + 10, 30, szMsg, strlen (szMsg));
                           break;
    }

    DrawObject (hDC, pObject);
  }

  EndPaint (hWnd, &ps);
}

/*
 * Processes the mensages WM_DESTROY
 */
static void Proj_OnDestroy (HWND hwnd)
{
  PostQuitMessage (0);
}

/*****************************************
 * Asks the user about the filename *
 *****************************************/
static BOOL GetFileName (HWND hWnd, char *pszFileName, int cMaxString)
{
  OPENFILENAME ofn;

  assert (pszFileName != NULL && cMaxString > 0);

  memset (&ofn, 0, sizeof (OPENFILENAME));

  ofn.lStructSize  = sizeof (OPENFILENAME); 
  ofn.hwndOwner    = hWnd; 
  ofn.lpstrFilter  = "Object Files\0*.PTS\0\0"; 
  ofn.nFilterIndex = 1;
  ofn.lpstrFile    = pszFileName; 
  ofn.nMaxFile     = cMaxString ; 
  ofn.Flags        = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY	| OFN_LONGNAMES	; 

  return GetOpenFileName (&ofn);
}


/*
 * Changes the check mark in the menu
 */
static void ChangeMenuOptions (HWND hWnd, int iOldOpt, int iNewOpt, int iMenu)
{
  HMENU  hMenu = GetSubMenu (GetMenu (hWnd), iMenu);
  CheckMenuItem (hMenu, iOldOpt, MF_UNCHECKED);
  CheckMenuItem (hMenu, iNewOpt, MF_CHECKED);
}

/*
 * Disables the options in iMenu menu.
 */
static void DisableMenuOptions (HWND hWnd, int iMenu)
{
  HMENU  hMenu = GetSubMenu (GetMenu (hWnd), iMenu);
  int i, iMax = GetMenuItemCount (hMenu);

  for (i = 0; i < iMax; i++) {
    CheckMenuItem (hMenu, i, MF_UNCHECKED | MF_BYPOSITION);
    EnableMenuItem (hMenu, i, MF_GRAYED | MF_BYPOSITION);
  }
  
}

/*
 * Enables the options in iMenu menu.
 */
static void EnableMenuOptions (HWND hWnd, int iMenu)
{
  HMENU  hMenu = GetSubMenu (GetMenu (hWnd), iMenu);
  int i, iMax = GetMenuItemCount (hMenu);

  for (i = 0; i < iMax; i++)
    EnableMenuItem (hMenu, i, MF_ENABLED | MF_BYPOSITION);
  
}


/*
 * Changes the variable value.
 */
static BOOL ModifyVar (double *pdValue, double dFactor, double dMin, double dMax, BOOL bOp)
{
  BOOL bRetValue = TRUE;

  if (bOp)
    if (*pdValue < dMax)
      *pdValue += dFactor;
    else
      bRetValue = FALSE;
  else
    if (*pdValue > dMin)
      *pdValue -= dFactor;
    else
      bRetValue = FALSE;

  return bRetValue;
}


/*
 * Processes the messages about changing view.
 */
static void ProcessOption (HWND hWnd, int iOption )
{
  static idLastOpt = IDM_MAIN;
  HMENU hMenu;
  MATRIX_4x4 matrix;

  ChangeMenuOptions (hWnd, idLastOpt, iOption, 1);
  idLastOpt = iOption;
  switch (iOption) {
    case IDM_MAIN : iParamOpt = 0;
                    DisableMenuOptions (hWnd, 2);
                    MatrixFront (matrix);
                    break;


    case IDM_SIDE:  iParamOpt = 0;
                    DisableMenuOptions (hWnd, 2);  
                    MatrixSide (matrix);
                    break;


    case IDM_TOP  : iParamOpt = 0;
                    DisableMenuOptions (hWnd, 2);
                    MatrixAbove (matrix);
                    break;

    case IDM_OBLIQUE :
                    if (iParamOpt != IDM_REDUCE_FACTOR && iParamOpt != IDM_ANGLE)  {
                      DisableMenuOptions (hWnd, 2);

                      hMenu = GetMenu (hWnd);
                      EnableMenuItem (hMenu, IDM_REDUCE_FACTOR, MF_ENABLED);
                      EnableMenuItem (hMenu, IDM_ANGLE, MF_ENABLED);

                      dFactor = 1;
                      dAngle  = 45.0; 
                      FORWARD_WM_COMMAND (hWnd, IDM_REDUCE_FACTOR, NULL, NULL, SendMessage);
                    }

                    MatrixOblique (matrix, dFactor, dAngle);
                    break;


    case IDM_PERSPECTIVE :
                    iParamOpt = iOption;
                    dDistance = 1;
                    DisableMenuOptions (hWnd, 2);
                    MatrixPerspective (matrix, dDistance);
                    break;

    case IDM_AXONOMETRIC : 
                    if (iParamOpt != IDM_A_FACTOR && iParamOpt != IDM_B_FACTOR)  {
                      DisableMenuOptions (hWnd, 2);

                      hMenu = GetMenu (hWnd);
                      EnableMenuItem (hMenu, IDM_A_FACTOR, MF_ENABLED);
                      EnableMenuItem (hMenu, IDM_B_FACTOR, MF_ENABLED);

                      dA = dB = 30.0; 
                      FORWARD_WM_COMMAND (hWnd, IDM_A_FACTOR, NULL, NULL, SendMessage);
                    }

                    MatrixAxonometric (matrix, dA, dB);
                    break;
  }
  
  DrawSetProjection (matrix);
  InvalidateRect (hWnd, NULL, TRUE);
  UpdateWindow (hWnd);
}


⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?