⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ccc_msw.cpp

📁 BigC++的源码
💻 CPP
字号:
/*

COPYRIGHT (C) 1994 - 2002 Cay S. Horstmann. All Rights Reserved.

NOTE TO STUDENTS: Do not attempt to study the contents of this file. You
can, and should, use the services provided in this file without knowing
the highly technical details of the implementation.

*/

#include <cmath>
#include <cstring>
#include <cstdlib>
#include <cstdio>

using namespace std;

#include "ccc_msw.h"

const double DEFAULT_XMIN = -10;
const double DEFAULT_YMIN = 10;
const double DEFAULT_XMAX = 10;
const double DEFAULT_YMAX = -10;

GraphicWindow cwin;

extern int ccc_win_main();

/*-------------------------------------------------------------------------*/

long FAR PASCAL /* _export */ ccc_win_proc(HWND hwnd, UINT message, UINT wParam, LONG lParam)
{  
   static int paint_flag = 1;   // tells WinProc to call ccc_win_main()
   PAINTSTRUCT ps; // the display's paint struct
   HDC mainwin_hdc;
   HINSTANCE hInstance;
  
   switch (message)
   {  
      case WM_PAINT:
         mainwin_hdc = BeginPaint(hwnd, &ps);

         if (paint_flag)
         {  
            paint_flag = false;       // flag must be set first in case
            cwin.open(hwnd, mainwin_hdc);
            ccc_win_main();
         }
         else
            cwin.repaint(ps);

         EndPaint(hwnd, &ps);
         break;

      case WM_DESTROY:
         cwin.close();
         exit(0); 
   }
   return DefWindowProc(hwnd, message, wParam, lParam);
}

/*-------------------------------------------------------------------------*/

int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
   LPSTR, int nShowCmd)
{  
   MSG msg;
   WNDCLASS wndclass;

   if (!hPrevInstance)
   {  
      wndclass.style = CS_HREDRAW | CS_VREDRAW;
      wndclass.lpfnWndProc = ccc_win_proc;
      wndclass.cbClsExtra = 0;
      wndclass.cbWndExtra = 0;
      wndclass.hInstance = hInstance;
      wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
      wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
      wndclass.hbrBackground = (HBRUSH)GetStockObject (WHITE_BRUSH);
      wndclass.lpszMenuName = NULL;
      wndclass.lpszClassName = "CCC_WIN";

      RegisterClass (&wndclass);
   }

   char title[80];
   GetModuleFileName(hInstance, title, sizeof(title));

   HWND hwnd = CreateWindow("CCC_WIN",
      title,
      WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      GetSystemMetrics(SM_CYFULLSCREEN) * 3 / 4,
      GetSystemMetrics(SM_CYFULLSCREEN) * 3 / 4,
      NULL,
      NULL,
      hInstance,
      0);

   ShowWindow(hwnd, nShowCmd);
   UpdateWindow(hwnd);

   while (GetMessage(&msg, NULL, 0, 0))
   {  
      TranslateMessage(&msg);
      DispatchMessage(&msg);
   }
   return msg.wParam;
}

/*-------------------------------------------------------------------------*/

GraphicWindow::GraphicWindow()
:  _user_xmin(DEFAULT_XMIN),
   _user_ymin(DEFAULT_YMIN),
   _user_xmax(DEFAULT_XMAX),
   _user_ymax(DEFAULT_YMAX)
{}

void GraphicWindow::open(HWND hwnd, HDC mainwin_hdc)
{  
   HINSTANCE hInstance = (HINSTANCE)
      GetWindowLong(hwnd, GWL_HINSTANCE);
   child_hwnd = CreateWindow("static",
      NULL,
      WS_CHILD | WS_VISIBLE, /* style */
      0,  /* x position */
      0,  /* y position */
      0,  /* width (x) */
      30, /* height (y) */
      hwnd,
      (HMENU)84,  /* child ID */
      hInstance,
      0);

   edit_hwnd  = CreateWindow("edit",
      NULL,
      WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_AUTOVSCROLL, /* style */
      0,  /* x position */
      0,  /* y position */
      0,  /* width (x) */
      30, /* height (y) */
      hwnd,
      (HMENU)85,  /* child ID */
      hInstance,
      0);

   RECT rect;
   GetClientRect(hwnd, &rect);
   _disp_xmax = rect.right - 1;
   _disp_ymax = rect.bottom - 1;

   _hdc = mainwin_hdc;

   SelectObject(_hdc, GetStockObject(NULL_BRUSH));
   SelectObject(_bitmap_hdc, GetStockObject(NULL_BRUSH));

   SelectObject(_hdc, GetStockObject(BLACK_PEN));
   SelectObject(_bitmap_hdc, GetStockObject(BLACK_PEN));

   SelectObject(_hdc, GetStockObject(SYSTEM_FONT));
   SelectObject(_bitmap_hdc, GetStockObject(SYSTEM_FONT));

   _bitmap_xmax = GetSystemMetrics(SM_CXFULLSCREEN);
   _bitmap_ymax = GetSystemMetrics(SM_CYFULLSCREEN);

   HDC hdc = GetDC(hwnd);
   _bitmap_hdc = CreateCompatibleDC(hdc);
   _hbm = CreateCompatibleBitmap(hdc, _bitmap_xmax, _bitmap_ymax);
   ReleaseDC(hwnd, hdc);
   if (!_hbm)
   {  
      MessageBox(hwnd, (LPSTR)"Memory problems in Bitmap Creation",
         (LPSTR)"CCC Error", MB_ICONHAND);
         SendMessage(hwnd, WM_DESTROY, 0, 0L);
         return;
   }
   _hbm_saved = (HBITMAP)SelectObject(_bitmap_hdc, _hbm);

   clear();
}

void GraphicWindow::clear()
{  
   COLORREF color = RGB(255, 255, 255);
   HBRUSH brush = CreateSolidBrush(color);
   HBRUSH saved_brush = (HBRUSH)SelectObject(_hdc, brush);
   PatBlt(_hdc, 0, 0, _disp_xmax, _disp_ymax, PATCOPY);
   SelectObject(_hdc, saved_brush);
   saved_brush = (HBRUSH)SelectObject(_bitmap_hdc, brush);
   PatBlt(_bitmap_hdc, 0, 0, _bitmap_xmax, _bitmap_ymax, PATCOPY);
   SelectObject(_bitmap_hdc, saved_brush);
   DeleteObject(brush);
}

void GraphicWindow::coord(double xmin, double ymin,
   double xmax, double ymax)
{  
   _user_xmin = xmin;
   _user_xmax = xmax;
   _user_ymin = ymin;
   _user_ymax = ymax;
}

int GraphicWindow::user_to_disp_x(double x) const
{  
   return (int) ((x - _user_xmin) * _disp_xmax / (_user_xmax - _user_xmin));
}

int GraphicWindow::user_to_disp_y(double y) const
{  
   return (int) ((y - _user_ymin) * _disp_ymax / (_user_ymax - _user_ymin));
}

double GraphicWindow::disp_to_user_x(int x) const
{  
   return (double)x * (_user_xmax - _user_xmin) / _disp_xmax + _user_xmin;
}

double GraphicWindow::disp_to_user_y(int y) const
{  
   return (double)y * (_user_ymax - _user_ymin) / _disp_ymax + _user_ymin;
}

void GraphicWindow::point(double x, double y)
{  
   const int POINT_RADIUS = 3;
   int disp_x = user_to_disp_x(x);
   int disp_y = user_to_disp_y(y);

#undef Ellipse
   Ellipse(_hdc, disp_x - POINT_RADIUS, disp_y - POINT_RADIUS,
      disp_x + POINT_RADIUS, disp_y + POINT_RADIUS);
   Ellipse(_bitmap_hdc, disp_x - POINT_RADIUS, disp_y - POINT_RADIUS,
      disp_x + POINT_RADIUS, disp_y + POINT_RADIUS);
#define Ellipse CCC_WIN_Ellipse
}

void GraphicWindow::ellipse(double x, double y, double ra, double rb)
{
#undef Ellipse
   Ellipse(_hdc, user_to_disp_x(x - ra), user_to_disp_y(y - rb),
      user_to_disp_x(x + ra),user_to_disp_y(y + rb));
   Ellipse(_bitmap_hdc, user_to_disp_x(x - ra), user_to_disp_y(y - rb),
      user_to_disp_x(x + ra),user_to_disp_y(y + rb));
#define Ellipse CCC_WIN_Ellipse
}

void GraphicWindow::line(double xfrom, double yfrom, double xto,
   double yto)
{
   MoveToEx(_hdc, user_to_disp_x(xfrom), user_to_disp_y(yfrom), 0);
   LineTo(_hdc,user_to_disp_x(xto), user_to_disp_y(yto));

   MoveToEx(_bitmap_hdc, user_to_disp_x(xfrom), user_to_disp_y(yfrom), 0);
   LineTo(_bitmap_hdc,user_to_disp_x(xto), user_to_disp_y(yto));
}

void GraphicWindow::text(string s, double x, double y)
{  
   const char* t = s.c_str();
   SetBkMode(_hdc, TRANSPARENT);
   TextOut(_hdc, user_to_disp_x(x), user_to_disp_y(y), t, lstrlen(t));
   SetBkMode(_bitmap_hdc, TRANSPARENT);
   TextOut(_bitmap_hdc, user_to_disp_x(x), user_to_disp_y(y), t, lstrlen(t));
}

void GraphicWindow::statusline_prompt(string s)
{  
   const int M_WIDTH = 30;
   const char* t = s.c_str();
   HDC child_hdc;

   child_hdc = GetDC(child_hwnd);
   SIZE sz;
   GetTextExtentPoint32(child_hdc, t, strlen(t), &sz);
   _mlength = sz.cx;
   GetTextExtentPoint32(child_hdc, " ", 1, &sz);
   _mlength += sz.cx;
   ReleaseDC(child_hwnd, child_hdc);
   MoveWindow (child_hwnd, 1, 0, _mlength, M_WIDTH, true);
   SendMessage (child_hwnd, WM_SETTEXT,0, (LPARAM) (LPCSTR) t);

   //move edit window from end of child window to edge of main window
   MoveWindow (edit_hwnd, cwin._mlength+1, 0, cwin._disp_xmax, M_WIDTH, true);
}

GraphicWindow& GraphicWindow::operator<<(Point p)
{  
   point(p.get_x(), p.get_y());
   return *this;
}

GraphicWindow& GraphicWindow::operator<<(Circle c)
{  
   ellipse(c.get_center().get_x(), c.get_center().get_y(), c.get_radius(), c.get_radius());
   return *this;
}

GraphicWindow& GraphicWindow::operator<<(Line s)
{  
   line(s.get_start().get_x(), s.get_start().get_y(), s.get_end().get_x(), s.get_end().get_y());
   return *this;
}

GraphicWindow& GraphicWindow::operator<<(Message t)
{  
   text(t.get_text(), t.get_start().get_x(), t.get_start().get_y());
   return *this;
}

string GraphicWindow::get_string(string out_string)
{  
   MSG msg;
   const int BUFFSIZE = 80;

   char buffer[BUFFSIZE];
   memset(buffer, 0, sizeof(buffer));
   SendMessage (edit_hwnd, WM_SETTEXT,0, (LPARAM) (LPCSTR) buffer);

   string temp;

   statusline_prompt(out_string);   // output prompt

   SetFocus(edit_hwnd);

   HWND phwnd = GetParent(child_hwnd);

   while (GetMessage(&msg, (HWND) NULL, 0, 0))
   {  
      TranslateMessage(&msg);
      DispatchMessage(&msg);

      switch(msg.message)
      {  
         case WM_KEYUP:
            if ((msg.wParam == VK_RETURN) || (msg.wParam == VK_ESCAPE))
            {  
               SendMessage (edit_hwnd, WM_GETTEXT,sizeof(buffer), (LPARAM) (LPCSTR) buffer);
               int buflen = strlen(buffer);
               if (buflen >= 2 && buffer[buflen - 2] == '\r') buffer[buflen - 2] = 0;
               temp = buffer;
               //shrink child windows after use

               MoveWindow (child_hwnd, 0, 0, 0, 0, true);
               MoveWindow (edit_hwnd, 0, 0, 0, 0, true);
               SetFocus(phwnd);
               return temp;
            }
            break;
      }
   }
   return temp; 
}

Point GraphicWindow::get_mouse(string outstr)
{  
   MSG msg;

   Point p;// = new point;
   int mouse_x, mouse_y;

   statusline_prompt(outstr);
   char buf[100];


   while (GetMessage(&msg, (HWND) NULL, 0, 0))
   {  
      TranslateMessage(&msg);
      DispatchMessage(&msg);
      switch(msg.message)
      {  
         case WM_LBUTTONDOWN:
            mouse_x = LOWORD(msg.lParam);
            mouse_y = HIWORD(msg.lParam);
            p = Point(disp_to_user_x(mouse_x), disp_to_user_y(mouse_y));
            MoveWindow (child_hwnd, 0, 0, 0, 0, true);
            MoveWindow (edit_hwnd, 0, 0, 0, 0, true);
            return p;

         case WM_MOUSEMOVE:
            mouse_x = LOWORD(msg.lParam);
            mouse_y = HIWORD(msg.lParam);
            sprintf(buf, "(%f,%f)",disp_to_user_x(mouse_x),disp_to_user_y(mouse_y)); 
            SendMessage(edit_hwnd, WM_SETTEXT, 0, (LPARAM)buf);
            break;
      }
   }

   return p;
}

void GraphicWindow::close()
{  
   SelectObject(_bitmap_hdc, _hbm_saved);
   DeleteDC(_bitmap_hdc);
   DeleteObject(_hbm);
}

void GraphicWindow::repaint(PAINTSTRUCT& ps)
{  
   BitBlt(ps.hdc, ps.rcPaint.left, ps.rcPaint.top,
      ps.rcPaint.right, ps.rcPaint.bottom, _bitmap_hdc,
      ps.rcPaint.left, ps.rcPaint.top, SRCCOPY);
}

int GraphicWindow::get_int(const string& out_string) 
{  
   return atoi(get_string(out_string).c_str()); 
}

double GraphicWindow::get_double(const string& out_string) 
{  
   return atof(get_string(out_string).c_str()); 
}

⌨️ 快捷键说明

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