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 + -
显示快捷键?