📄 ccc_msw.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 + -