程序5-2 Sinewave

program Sinewave;

uses
  Windows,
  Messages,
  Math;
const
  NUM = 1000;

function WndProc(hWindow: HWND; msg, wParam, lParam: LongInt): LRESULT; stdcall;
const
  TWOPI = (2 * 3.1415926);
{$J+}
  cxClient: integer = 0;
  cyClient: integer = 0;
  hPen: HPEN = 0;
{$J-}
var
  ps: TPaintStruct;
  i: Integer;
  hdc1: HDC;
  hOldPen: HPEN;
  apt: array[0..NUM-1] of TPoint;
  pt: TPoint;
begin
  Result:= 0;
  case msg of
  WM_CREATE:
  begin
    hPen:= CreatePen(PS_SOLID, 2, RGB(255, 0, 0));
  end;
  WM_DESTROY:
  begin
    DeleteObject(hPen);
    PostQuitMessage(0);
  end;
  WM_SIZE:
  begin
    cxClient:= LoWord(lParam);
    cyClient:= HiWord(lParam);
  end;
  WM_PAINT:
  begin
    hdc1:= BeginPaint(hWindow, ps);
    //pi;
    //for i := 0 to NUM - 1 do
    //更改畫筆顏色
    SelectObject(hdc1, hPen);
    //更改座標系
    SetMapMode(hdc1, MM_LOMETRIC);
    SetViewportOrgEx(hdc1, 0, cyClient div 2, nil);
    //注意以下繪製函數使用的邏輯單位都不是像素,而是0.01mm
    //先繪製一條水平線即X軸
    pt.X:= cxClient;
    pt.Y:= cyClient;
    DPtoLP(hdc1, pt, 1);
    //此時pt.x, pt.y值表示爲客戶區右下角的點,用0.01單位
//    MoveToEx(hdc1, 0, 0, nil);
//    LineTo(hdc1, pt.X, pt.Y);
    MoveToEx(hdc1, 0, 0, nil);
    LineTo(hdc1, pt.X, 0); //繪製X軸
    MoveToEx(hdc1, 0, 0, nil);
    LineTo(hdc1, 0, -pt.y); //繪製Y軸,注意由於pt.y表示的是客戶區最底端的值因此它爲負值,
                            //爲了繪製上半軸,因此要添加負號。
    //計算Sin值,並保存到數組中
    for I := 0 to NUM-1 do
    begin
      //apt[i].X:= Trunc(I * (2*pi / NUM));
      apt[i].X:= I * pt.X div NUM;
      //繪製X軸的刻度
      MoveToEx(hdc1, apt[i].X, 0, nil);
      LineTo(hdc1, apt[i].X, 11);
      //函數值計算出來後,需要放大幾倍,否則取整後爲零。
      apt[i].Y:= Trunc(Sin(I * (2 * Pi / NUM)) * (-pt.Y div 2));

    end;

    //繪製Sin函數
    Polyline(hdc1, apt, NUM);
    EndPaint(hWindow, ps);
  end
  else
    Result:= DefWindowProc(hWindow, msg, wParam, lParam);
  end;
end;


const
  szAppName = 'SineWave';
var
  wndclass1: TWndClass;
  hWindow: HWND;
  msg: TMsg;
begin
  wndclass1.style:= CS_VREDRAW or CS_HREDRAW;
  wndclass1.lpfnWndProc:= @WndProc;
  wndclass1.cbClsExtra:= 0;
  wndclass1.cbWndExtra:= 0;
  wndclass1.hInstance:= HInstance;
  wndclass1.hIcon:= LoadIcon(0, IDI_APPLICATION);
  wndclass1.hCursor:= LoadCursor(0, IDC_ARROW);
  wndclass1.hbrBackground:= GetStockObject(WHITE_BRUSH);
  wndclass1.lpszMenuName:= nil;
  wndclass1.lpszClassName:= szAppName;

  if RegisterClass(wndclass1) = 0 then
  begin
    MessageBox(0, 'Program requires Windows NT!', szAppName, MB_ICONERROR);
    Exit;
  end;

  hWindow:= CreateWindow(szAppName, 'Sine Wave Using Polyline', WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, HInstance, nil);

  ShowWindow(hWindow, CmdShow);
  UpdateWindow(hWindow);

  while GetMessage(msg, 0, 0, 0) do
  begin
    TranslateMessage(msg);
    DispatchMessage(msg);
  end;
end.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章