Hướng dẫn lập trình VC++ 6.0, mô phỏng điều khiển, gia công CNC

Trong sự phát triển ngày càng lớn mạnh của khoa học công nghệ, vấn đề kết hợp các lĩnh vực điện tử - tin học và cơ khí đang rất được quan tâm .Một trong những đề tài thu hút được sự quan tâm của các sinh viên cơ khí đó là sử dụng ngôn ngữ lập trình để tạo ra các ứng dụng điều khiển và mô phỏng quá trình của máy móc. Một trong những công cụ lập trình hiệu quả và đạt kết quả tốt đó chính là Visual C++, được xây dựng trên nền tảng là ngôn ngữ lập trình hướng đối tượng C++. Trong bản đồ án tốt nghiệp với đề tài là “Hướng dẫn lập trình VC++ 6.0” sẽ trình bày những cách thức làm việc hiệu quả và cơ bản với ngôn ngữ lập trình này , kèm theo đó là các bài minh hoạ . Nội dung của đồ án tốt nghiệp như sau : -Phần I : Tổng quan về lập trình hướng đối tượng -Phần II : Visual C++ 6.0 -Phần III : Hướng dẫn lập trình +Chương 1 :thao tác với các hàm, biến. +Chương 2 : tạo menu, toolbar và các thao tác cơ bản +Chương 3 : sử dụng Font và giờ hệ thống . +Chương 4 : đọc, hiển thị và lưu file text. +Chương 5 : sử dụng Active X để đưa âm thanh vào trong ứng dụng. +Chương 6 : Giao tiếp máy tính . +Chương 7 : VC++ với thiết kế 3D. +Chương 8 : đóng gói chương trình, tạo bộ cài đặt. +Chương 9 : thiết kế mô phỏng chương trình điều khiển, mô phỏng gia công máy CNC. Do giới hạn về mặt thời gian cũng như những hạn chế về mặt kiến thức của người viết nên không thể tránh khỏi những sai sót vì vậy rất mong được sự thông cảm của người đọc. Trong quá trình hoàn thành đề tài ,được sự hướng dẫn tận tình của TS.Bùi Quý Lực , công việc đã được hoàn thành đúng tiến độ. Xin chân thành cảm ơn tới thầy Bùi Quý Lực .

doc159 trang | Chia sẻ: lvcdongnoi | Lượt xem: 2718 | Lượt tải: 1download
Bạn đang xem trước 20 trang tài liệu Hướng dẫn lập trình VC++ 6.0, mô phỏng điều khiển, gia công CNC, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
dụng các Active này bằng cách chọn Project >Add To Project >Components and Controls trên thanh menu , trong hộp thoại mở ra tiếp theo chọn Registered ActiveX Controls để tìm đến thư mục chứa các Active X này . Tìm đến Active X Microsoft Forms 2.0 CommandButton sử dụng để tạo các nút bấm, kích chọn nó và bấm Insert , trong hộp thoại Confirm Classes chỉ chọn lớp CCommandButton để đưa vào ứng dụng , ấn OK để hoàn tất .Sau khi chọn Active X này trong chương trình sẽ có sự hiện diện của lớp CCommandButton . Tiếp theo sử dụng thêm một Active X nữa là Microsoft Forms 2.0 TextBox để dễ dàng cho việc hiển thị, trong hộp thoại Confirm Classes chỉ chọn lớp CMdcText . Trên thanh công cụ Control lúc này có 2 Active X này và cách sử dụng chúng giống như các thành phần khác và thông số của nó có thể chỉnh sửa được nhờ thay đổi thuộc tính của nó. Để cho giao diện trông bắt mắt cần có các Icon hoặc ảnh Bitmap phù hợp để đưa chúng lên các nút bấm . Để chỉnh sửa vị trí các nút bấm (căn lề, sửa kích thước ) nhờ menu Layout . Kích chọn Microsoft Form 2.0 CommandButton và tạo ra các nút bấm như yêu cầu, căn chỉnh vị trí. Để tạo màu nền của các nút bấm cũng như đưa ảnh Bitmap lên chúng bằng việc sửa đổi thuộc tính Properties của chúng (Kích chuột phải vào các nút bấm chọn Properties). Sửa các thông số sau để có kết quả như mong muốn : -Autosize : là thuộc tính tự động thay đổi kích thước của nút bấm (để mặc định False để làm vô hiệu lực tham số này ). -BackColor : là thuộc tính liên quan đến màu sắc nền của các nút bấm, ở đây kích chọn mũi tên bên phía phải để chọn màu, muốn có các nút bấm có màu giống nhau chỉ việc chọn cùng tham số . -Caption : chính là tên mà nút bấm sẽ hiển thị (chẳng hạn nút bấm Open thì để Caption là Open. ..). -Enable : là thuộc tính liên quan đến việc làm cho có hoặc nút bấm không có hiệu lực, tuỳ lúc để thay đổi thuộc tính này nhờ các lệnh trong lớp CCommandButton. -Font : chữ hiện thị trên nút bấm sẽ có font là font lấy ở thuộc tính này. -ForeColor : là thuộc tính về màu chữ trên nút bấm. -Locked :thuộc tính có liên quan đến tác động lên nút bấm, có thể tác động được ( nếu để false) và không tác động được (nếu để True). -Picture : chọn đường dẫn tới file ảnh Bitmap hoặc Icon cần đưa lên nút bấm (ở đây nên chọn các Bitmap hay icon có kích thước phù hợp với kích thước nút bấm ). Sử dụng Microsoft Form 2.0 TextBox cũng tương tự như với CommandButton .Còn lại các Editbox để hiển thị toạ độ được tạo ra bằng cách kích chọn EditBox trong thanh công cụ Control .Sử dụng một thành phần Picture để dưới chế độ Frame và màu trắng để làm bảng mô phỏng quá trình gia công. Giao diện chính được thiết kế như sau : Hình 3.98 .Giao diện chính của chương trình. Đặt hộp thoại này là IDD_CNCCONTROLLER_DIALOG. Bảng điều khiển theo các thông tin : Số TT Đối tượng Đặc tính Cài đặt 1 Command Button ID Back Color Caption Fore Color Picture IDC_COMMAND_OPEN 0x00D2FFA6 Open 0x00800000 (Bitmap) 2 Command Button ID Caption IDC_COMMAND_NEW New 3 Command Button ID Caption IDC_COMMAND_EDIT_CODE Edit Code 4 Command Button ID Caption IDC_COMMAND_SAVE Save 5 Command Button ID Caption IDC_COMMAND_SAVE_AS Save As 6 Command Button ID Caption IDC_COMMAND_CONFIGURE Configure 7 Command Button ID Caption IDC_COMMAND_RUN Run 8 Command Button ID Caption IDC_COMMAND_STOP Stop 9 Static Text ID Caption IDC_STATIC (để trống ) 10 Command Button ID Back Color Font Caption Fore Color Locked Picture IDC_COMMAND_UPLEFT 0x00FFFFFF Time New Roman (để trống) 0x80000012 True (Bitmap) 11 Command Button ID IDC_COMMAND_UP 12 Command Button ID IDC_COMMAND_UPRIGHT 13 Command Button ID IDC_COMMAND_LEFT 14 Command Button ID IDC_COMMAND_CENTER 15 Command Button ID IDC_COMMAND_RIGHT 16 Command Button ID IDC_COMMAND_DOWNLEFT 17 Command Button ID IDC_COMMAND_DOWN 18 Command Button ID IDC_COMMAND_DOWNRIGHT 19 Command Button ID IDC_COMMAND_UPZ 20 Command Button ID IDC_COMMAND_DOWNZ (Tất cả các Command Button từ 6-20 có các thuộc tính còn lại giống nhau). 21 Command Button ID Caption Locked IDC_COMMAND_RESET Reset True 22 Command Button ID Caption IDC_COMMAND_SET_TOOL Set Tool 23 Command Button ID Caption Locked IDC_COMMAND_ZEROPOINT M Point True 24 Command Button ID Caption IDC_COMMAND_TOANYPOINT To Point 25 Command Button ID Caption IDC_COMMAND_APPLY Apply 26 Edit Box ID IDC_EDIT_TDX 27 Edit Box ID IDC_EDIT_TDY 28 Edit Box ID IDC_EDIT_TDZ 29 Static Text ID Extended IDC_STATIC_DANGDOCFILE Client Edge (chọn ) Static Edge (chọn ) 30 Microsoft Form 2.0 TextBox ID AutoSize Back Color Font Fore Color Locked Multiline ScrollBars IDC_TEXTBOX False 0x00FFFF00 Times New Roman 0x80000008 True True 3-Both 31 Picture ID IDC_HT 3.9.2.2.Thiết kế các hộp thoại phụ : -Hộp thoại Configure : Kích chuột phải vào CNCController resources >chọn Insert >Dialog >New. Lúc này tạo được một hộp thoại mới, kích chuột phải vào hộp thoại trong vùng soạn thảo và chọn Properties để ID là IDD_DIALOG_CONFIGURE và Caption đặt là Configure Hình 3.99 .Hộp thoại Configure. Bảng điều khiển : Số TT Đối tượng Đặc tính Cài đặt 1 Static Text ID Caption IDC_STATIC &Step X 2 Edit Box ID IDC_CONFIGURE_STEPX 3 Static Text ID Caption IDC_STATIC &Step Y 4 Edit Box ID IDC_CONFIGURE_STEPY 5 Static Text ID Caption IDC_STATIC &Step Z 6 Edit Box ID IDC_CONFIGURE_STEPZ 7 Group Box ID Caption IDC_STATIC &Moving Step 8 Radio Button ID Caption General IDC_RADIO_UNITMM &Mm Group (chọn) 9 Radio Button ID IDC_RADIO_UNITINCH Caption General &Inch Group( không chọn) 10 Group Box ID Caption IDC_STATIC &Unit 11 Edit Box ID IDC_CONFIGURE_VELOCITY 12 Static Text ID Caption IDC_STATIC &Velocity\n (Round/Min) 13 Button ID Caption IDC_CONFIGURE_APPLY &Apply 14 Button ID Caption IDC_CONFIGURE_DEFAULT &Default Hộp thoại này chỉ đơn giản là các EditBox (step X, StepY, Step Z) , các Radio button (inch, mm) một trong 2 radio button này phải chọn thuộc tính Group (để chỉ có thể chọn một nút này và không thể xảy ra đồng thời cả 2 nút được chọn ). Các nút bấm Apply, Default , các Static “Step X, StepY, Step Z, Velocity(Round/Min) và các group box “Moving Step “ và “Unit”. Ấn Ctrl +W : và chọn Create New Class, đặt tên lớp mới là CConfigureDlg -Hộp thoại Define Zero Point : Hình 3.100. Hộp thoại Define Zero Point Bảng điều khiển : Số TT Đối tượng Đặc tính Cài đặt 1 Dialog ID Caption IDD_DIALOG_DIEMGOC Define Zero Point 2 Static Text ID Caption IDC_STATIC X 3 Edit Box ID IDC_EDIT_TOADOX 4 Static Text ID Caption IDC_STATIC Y 5 Edit Box ID IDC_EDIT_TOADOY 6 CommandButton ID Caption IDC_COMMAND_APPLYZERO Apply 7 CommandButton ID Caption IDC_COMMAND_RESET Reset Hộp thoại này sẽ cho phép nhập toạ độ điểm khởi đầu của dao thông qua các Edit Box. Ấn Ctrl+W chọn Create New Class và đặt tên lớp là CDiemGoclg. -Hộp thoại Edit Code : Hình 3.101.Hộp thoại Edit Code. Bảng điều khiển : Số TT Đối tượng Đặc tính Cài đặt 1 Dialog ID Caption IDD_DIALOG_EDIT_CODE Edit Code 2 Edit Box ID Styles IDC_EDITCODE_EDIT Multiline (chọn) Vertical Scroll (chọn) Want Return( chọn) Uppercase (chọn) 3 CommandButton ID Caption IDC_EDITCODE_OK Ok 4 CommandButton ID Caption IDC_EDITCODE_CANCEL Cancel Edit Box với thuộc tính Style : đặt Multiline (để có thể gõ được nhiều dòng) , để Vertical scroll (để tạo thanh trượt ), kích chọn Want return ( để làm hiệu lực khi ấn Enter). Ấn Ctrl +W : và chọn Create New Class, đặt tên lớp mới là CEditCodeDlg -Hộp Thoại New G-code : Hình 3.102.Hộp thoại New G-Code. Bảng điều khiển : Số TT Đối tượng Đặc tính Cài đặt 1 Dialog ID Caption IDD_DIALOG_NEW New G-Code 2 Edit Box ID Styles IDC_DIALOG_EDIT_CODE Multiline (chọn) Vertical Scroll (chọn) Want Return( chọn) Uppercase (chọn) 3 CommandButton ID Caption IDC_NEWCODE_OK Ok 4 CommandButton ID Caption IDC_ NEWCODE _CANCEL Cancel Ấn Ctrl +W chọn Create New Class và đặt tên lớp này là CNewCodeDlg . -Hộp thoại Tool Demension : Hình 3.103. Tool Demension. Bảng điều khiển : Số tt Đối tượng Đặc tính Cài đặt 1 Dialog ID Caption IDD_DIALOG_SET_TOOL Tool Demension 2 Static Text ID Caption IDC_STATIC Radius 3 Edit Box ID IDC_SET_TOOL_RADIUS 4 Button ID Caption IDOK &Apply 5 Button ID Caption IDC_SET_TOOL_DEFAULT &Default Ấn Ctrl+ W chọn Create New Class và đặt tên lớp là CSetToolDlg -Hộp thoại To Any Point : Hình 3.104. Hộp thoại To Any Point . Bảng điều khiển : Số tt Đối tượng Đặc tính Cài đặt 1 Dialog ID Caption IDD_DIALOG_TOANYPOINT To Any Point 2 Static Text ID Caption IDC_STATIC To X 3 Edit Box ID IDC_EDIT_TOX 4 Static Text ID Caption IDC_STATIC To Y 5 Edit Box ID IDC_EDIT_TOY 6 Static Text ID Caption IDC_STATIC &Moving\n step 7 Edit Box ID IDC_EDIT_BUFFER 8 Button ID Caption IDOK OK 9 Button ID Caption IDCANCEL Cancel Ấn Ctrl +W chọn Create New Class và đặt tên lớp là CToAnyPointDlg -Hộp thoại About CNC Controller : Số tt Đối tượng Đặc tính Cài đặt 1 Dialog ID Caption IDD_ABOUTBOX About CNCController 2 Picture ID General IDC_STATIC Type : Bitmap Image : IDB_BITMAP_BKHN Trong hộp thoại này chứa thông tin về ứng dụng do người viết đưa vào . Ảnh Bitmap có ID là IDB_BITMAP_BKHN là một Bitmap được tạo sẵn bên ngoài và đưa vào ứng dụng bằng thao tác kích chuột phải vào CNCController resources >Insert > Bitmap>Import và chọn tới đường dẫn chứa Bitmap, đổi ID của bitmap thành IDB_BITMAP_BKHN . 3.9.2.3.Thiết kế thanh menu : Trong CNCController resources mở rộng mục Menu, kích đúp vào IDR_MENU, bên màn hình soạn thảo, tạo các thành phần của menu như sau : -Mục File : Số tt Đối tượng Đặc tính Cài đặt 1 Menu Item ID Caption ID_FILE_NEW &New\t Ctrl+N 2 Menu Item ID Caption ID_FILE_OPEN &Open\t Ctrl+O 3 Menu Item ID Caption ID_FILE_EDIT_CODE &Edit Code 4 Menu Item ID Caption ID_FILE_SAVE &Save\t Ctrl+S 5 Menu Item ID Caption ID_FILE_SAVE_AS &Save As\t Shift+S 6 Menu Item ID Caption ID_FILE_EXIT &Exit\t Q -Mục Action : Số tt Đối tượng Đặc tính Cài đặt 1 Menu Item ID Caption ID_TOOL_CONFIGURE &Configure 2 Menu Item ID Caption ID_TOOL_RUN &Run 3 Menu Item ID Caption ID_TOOL_STOP &Stop -Mục Help : Số tt Đối tượng Đặc tính Cài đặt 1 Menu Item ID Caption ID_HELP_ABOUTCNCCONTROLLER &About CNC Controller Ở trên sử dụng “…\t ..” để tạo ra tổ hợp phím tắt, để tổ hợp phím tắt có tác dụng phải thêm thành phần Accelerator vào trong ứng dụng . Kích chuột phải vào CNCController resources >Insert> chọn Accelerator. Ứng dụng tạo ra một Accelerator có ID là IDR_ACCELERATOR. Kích chuột vào nó, trên màn hình soạn thảo bên phải kích đúp vào các dòng trắng để hiện ra bảng Accel Properties Hình 3.105. Thuộc tính của Accelerator Trong ô ID chọn các thành phần muốn tạo phím tắt, ở ô Key sẽ là phím được ấn sau phím chức năng Ctrl, Alt hoặc Shift được chọn ở ô Modifiers, chọn kiểu VirtKey . ID Key Type ID_FILE_NEW Ctrl+N VIRTKEY ID_FILE_OPEN Ctrl+O VIRTKEY ID_FILE_EXIT Ctrl+Q VIRTKEY ID_FILE_SAVE Ctrl+S VIRTKEY ID_FILE_SAVES Shift+S VIRTKEY Phần giao diện đến đây đã hoàn thành. 3.9.3.Viết code cho chương trình : 3.9.3.1.Viết code cho hộp thoại Configure : Thêm các biến điều khiển : ID Kiểu Biến IDC_CONFIGURE_STEPX double m_ConfigureStepX IDC_CONFIGURE_STEPY double m_ConfigureStepY IDC_CONFIGURE_STEPZ double m_ConfigureStepZ IDC_CONFIGURE_ VELOCITY double m_ConfigureVelocity ID Kiểu Biến IDC_RADIO_UNITMM int m_Sel Chức năng của hộp thoại sẽ là nhập các thông số về bước tiến theo trục X, Y, Z, tốc độ và đơn vị được sử dụng, sau khi nhập thông số ấn “Apply” để nạp tham số hoặc ấn Default để trở về giá trị mặc định , vì vậy sẽ chỉ viết lệnh cho 2 sự kiện nút bấm Apply và nút bấm Default : Ấn Ctrl+W, trong hộp thoại MFC ClassWizard chọn ClassName là CConfigureDlg, chọn Object IDs là IDC_CONFIGURE_APPLY, trong ô Message chọn BN_CLICKED >Add Function >Edit Code : void CConfigureDlg::OnConfigureApply( ) { OnOK( ); } Với nút bấm Default cũng làm tương tự : void CConfigureDlg::OnConfigureDefault( ) { m_ConfigureStepX=1.5; m_ConfigureStepY=1.5; m_ConfigureStepZ=1.5; m_ConfigureVelocity=1000; m_Sel = 0; UpdateData(FALSE); } Di chuyển con trỏ lên đầu dòng và sửa lại hàm CConfigureDlg(CWnd* pParent /*=NULL*/) như sau : CConfigureDlg::CConfigureDlg(CWnd* pParent /*=NULL*/) : CDialog(CConfigureDlg::IDD, pParent) { //{{AFX_DATA_INIT(CConfigureDlg) m_ConfigureStepX = 1.5; m_ConfigureStepY = 1.5; m_ConfigureStepZ = 1.5; m_ConfigureVelocity = 1000.0; m_Sel = 0; //}}AFX_DATA_INIT } Các thông số trong hộp thoại này sẽ được nhập vào bộ nhớ chương trình và sẽ được tái lập vào chương trình chính thông qua sự kiện mở hộp thoại Configure. 3.9.3.2.Viết code cho hộp thoại Define Zero Point (IDD_DIALOG_DIEMGOC) . Ấn Ctrl +W, chọn Class Name là CdiemGocDlg, thêm các biến điều khiển như sau : ID Kiểu biến Biến IDC_EDIT_TOADOX double m_ToolX IDC_EDIT_TOADOY double m_ToolY Hộp thoại này sẽ có nhiệm vụ nhập toạ độ ban đầu của đầu dao thông qua các biến m_ToolX, m_ToolY , giá trị sẽ được gọi vào chương trình chính thông qua sự kiện mở hộp thoại (nhờ nút bấm MPoint ở giao diện chính ). Tác động sự kiện Click với các nút bấm Apply(IDC_COMMAND_APPLYZERO)và Reset (IDC_COMMAND_RESETZERO): void CDiemGocDlg::OnClickCommandApplyzero( ) { OnOK( ); } void CDiemGocDlg::OnClickCommandResetzero( ) { m_ToolX=0; m_ToolY=0; UpdateData(FALSE); return; } 3.9.3.3.Viết Code cho hộp thoại Edit Code(IDD_DIALOG_EDIT_CODE) : Thêm biến điều khiển : ID Kiểu biến Biến IDC_EDITCODE_EDIT CString m_strEditCode Hộp thoại này sẽ có nhiệm vụ sửa lại nội dung của các đoạn Text và sau đó hiển thị trở lại trên TextBox hiển thị. Tác động sự kiện Click với các nút bấm Ok và Cancel : void CEditCodeDlg::OnClickEditcodeCancel( ) { m_strEditCode=""; //Khởi tạo cho Edit box không có kí tự nào UpdateData(FALSE); return; //Quay trở lại hộp thoại Edit Code khi ấn nút Cancel } void CEditCodeDlg::OnClickEditcodeOk( ) { OnOK( ); //Thoát khỏi hộp thoại khi ấn nút OK } 3.9.3.4.Viết Code cho hộp thoại New : Hộp thoại này cũng gần tương tự hộp thoại Edit Code tuy nhiên nó sẽ tạo ra một đoạn văn bản mới, khi tắt hộp thoại nội dung sẽ được hiển thị lên TextBox hiển thị. Biến điều khiển : ID Kiểu biến Biến IDC_DIALOG_EDIT_CODE CString m_strNewEditCode Tác động sự kiện Click lên 2 nút CommandButton OK(IDC_NEWCODE_OK) và nút Cancel (IDC_NEWCODE_CANCEL). void CNewCodeDlg::OnClickNewcodeOk() { OnOK(); } void CNewCodeDlg::OnClickNewcodeCancel() { m_strNewEditCode=""; UpdateData(FALSE); return; } 3.9.3.5.Viết code cho hộp thoại Tool Demension (IDD_DIALOG_SET_TOOL ) : Kích thước của dụng cụ cắt sẽ được thay đổi thông qua hộp thoại này .Thêm biến điều khiển : ID Kiểu biến Biến IDC_SET_TOOL_RADIUS int m_Radius Tác động sự kiện BN_CLICKED lên 2 Button Apply(IDOK) và Default (IDC_SET_TOOL_DEFAULT): void CSetToolDlg::OnSetToolDefault( ) { m_Radius=5; UpdateData(FALSE); } void CSetToolDlg::OnOK( ) { CDialog::OnOK( ); } 3.9.3.6.Viết code cho hộp thoại To Any Point (IDD_DIALOG_TOANYPOINT) : Hộp thoại này sẽ nhập toạ độ của điểm cần đưa dụng cụ cắt tới với tốc độ định trước, thêm các biến như sau : ID Kiểu biến Biến IDC_EDIT_BUFFER double m_Buffer IDC_EDIT_TOX double m_ToX IDC_EDIT_TOY double m_ToY Tác động sự kiện BN_CLICKED lên 2 nút bấm Ok và Cancel : void CToAnyPointDlg::OnOK( ) { CDialog::OnOK( ); } void CToAnyPointDlg::OnCancel( ) { CDialog::OnCancel( ); } 3.9.3.7.Viết code cho chương trình chính Nội dung của chương trình chính sẽ bao gồm : -Khai báo các biến điều khiển dối tượng , các biến và các hàm sử dụng trong chương trình . -Gộp các file để sử dụng được các hộp thoại phụ. -Sử dụng các chú thích trong ứng dụng . -Vẽ lên nền giao diện các bảng màu và chữ viết -Vẽ vùng hiển thị( bao gồm hệ toạ độ và dụng cụ cắt ). -Gọi và truyền tham số cho các hàm hiển thị . -Viết mã lệnh cho các nút bấm và menu -Sử dụng SetTimer để mô phỏng quá trình gia công. -Chuyển mã G-Code thành các lệnh mô phỏng gia công. Hình 3.106.Sơ đồ khối thuật toán mô phỏng gia công theo đường thẳng Tất cả các khai báo sẽ được tiến hành với CNCControllerDlg.h và các mã lệnh sẽ được viết với CNCControllerDlg.cpp (trong mục File View. Thêm các biến điều khiển (hộp thoại IDD_CNCCONTROLLER_DIALOG Ấn Ctrl+W, chọn Member Variable, chọn ID Object >Add Variable ): ID Biến Kiểu biến IDC_COMMAND_CENTER m_Center CCommandButton IDC_COMMAND_CONFIGURE m_Configure CCommandButton IDC_COMMAND_DOWN m_Down CCommandButton IDC_COMMAND_DOWNLEFT m_DownLeft CCommandButton IDC_COMMAND_DOWNRIGHT m_DownRight CCommandButton ID Biến Kiểu biến IDC_COMMAND_DOWNZ m_DownZ CCommandButton IDC_COMMAND_EDIT_CODE m_EditCode CCommandButton IDC_COMMAND_LEFT m_Left CCommandButton IDC_COMMAND_NEW m_New CCommandButton IDC_COMMAND_OPEN m_Open CCommandButton IDC_COMMAND_RESET m_Reset CCommandButton IDC_COMMAND_RIGHT m_Right CCommandButton IDC_COMMAND_RUN m_Run CCommandButton IDC_COMMAND_SAVE m_Save CCommandButton IDC_COMMAND_SAVE_AS m_SaveAs CCommandButton IDC_COMMAND_STOP m_Stop CCommandButton IDC_COMMAND_UP m_Up CCommandButton IDC_COMMAND_UPLEFT m_UpLeft CCommandButton IDC_COMMAND_UPRIGHT m_UpRight CCommandButton IDC_COMMAND_UPZ m_UpZ CCommandButton IDC_COMMAND_ZEROPOINT m_Zero CCommandButton IDC_EDIT_TDX m_htToaDoXTool float IDC_EDIT_TDY m_htToaDoYTool float IDC_TEXTBOX m_DieuKhienTextBox CMdcText Thêm các biến cần thiết khác ( tìm đến CNCControllerDlg.h trong Resources) : class CCNCControllerDlg : public CDialog { ……………………. DECLARE_MESSAGE_MAP( ) public: Cstring DuongDanFile,TenFile,str,m_ChuDichChuyen,ThamSoTruyen ; CString ToaDoChuotX,ToaDoChuotY,DuongDanFileSave; HACCEL m_hAccel; //Biến này sẽ được dùng để sử dụng được tổ hợp các phím tắt CString strX,strY; private: void WriteText(CDC*pDC); //Hàm này dùng để viết chữ lên màn hình void DrawGreen(CDC*pDC); // Hàm này dùng để vẽ màn hình void KhungHienThi(CDC*pDC); // Vẽ nền khung hiển thị void DrawToolCut(CDC *pDC, int xc, int yc, int r, COLORREF crColor); //Vẽ dụng cụ cắt, với các tham số có thể thay đổi void DrawAxis(CDC*pDC); //Vẽ trục toạ độ void ChuyenMaGCode(char GCode[800001]); // Hàm này thực hiện chức năng dịch mã G-Code để mô phỏng CToolTipCtrl ChuThich; // Sử dụng biến này để tạo ra các dòng chú thích CDC pCuaSoManHinh; // Sử dụng làm thiết bị ngữ cảnh CBitmap BCuaSo; // Lưu giữ màn hình thành một Bitmap hiển thị CString m_strDichChuyen; //Dòng chữ này sẽ được hiển thị và cho chạy trên màn hình double yc,bufferyc,m_ToX,m_ToY,m_buffer; // Các biến lưu giữ các thông số được truyền xuống từ các hộp thoại double xc,bufferxc; double zc,bufferzc,bufferVelocity; int RTool; // Bán kính dụng cụ cắt . }; Để sử dụng được các hộp thoại phụ phải tiến hành gộp file trong CNCControllerDlg.cpp : #include "NewCodeDlg.h" #include "EditCodeDlg.h" #include "ConfigureDlg.h" #include "DiemGocDlg.h" #include "SetToolDlg.h" #include "ToAnyPointDlg.h" Đưa chức năng sử dụng phím tắt vào trong ứng dụng, tìm đến hàm CCNCControllerDlg::CCNCControllerDlg(CWnd* pParent /*=NULL*/) : CDialog(CCNCControllerDlg::IDD, pParent) { …………. m_hAccel=::LoadAccelerators(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_ACCELERATOR)); } Bây giờ khi bấm tổ hợp phím tắt sẽ có tác dụng . -Tạo các dòng chú thích khi chuột di chuyển tới các nút bấm di chuyển : Để làm được điều này cần thực hiện các bước *B1 : tạo ra một kiểu chú thích . *B2 : làm cho chú thích có hiệu lực . *B3 : tạo ra màu nền chú thích và màu của dòng chú thích. *B4 : gán nội dung chú thích cho các đối tượng *B5 : Relay để hiển thị được chú thích . Các bước 1->4 sẽ được thực hiện trong hàm OnInitDialog, B5 sẽ phải sử dụng sự kiện PreTranslateMessage (ấn Ctrl+W, chọn lớp CNCControllerDlg, Object IDs là CNCControllerDlg và Message là PreTranslateMessage >Add Function >Ok) BOOL CCNCControllerDlg::OnInitDialog( ) { CDialog::OnInitDialog( ); …………………………………………. ChuThich.Create(this); //B1 :Tạo Chú thích ChuThich.Activate(TRUE); //B2 :Làm cho chú thích có hiệu lực ChuThich.SetTipBkColor(RGB(255,255,255)); ChuThich.SetTipTextColor(RGB(0,0,128)); //B3 : Đặt màu nền và màu chữ cho dòng chú thích ChuThich.AddTool(GetDlgItem(IDC_COMMAND_UP),"Go up"); ChuThich.AddTool(GetDlgItem(IDC_COMMAND_UPLEFT),"Go Up-Left"); ChuThich.AddTool(GetDlgItem(IDC_COMMAND_UPRIGHT),"Go Up-Right"); ChuThich.AddTool(GetDlgItem(IDC_COMMAND_DOWNLEFT),"Go Down-Left"); ChuThich.AddTool(GetDlgItem(IDC_COMMAND_DOWNRIGHT),"Go Down-Right"); ChuThich.AddTool(GetDlgItem(IDC_COMMAND_DOWN),"Go Down"); ChuThich.AddTool(GetDlgItem(IDC_COMMAND_LEFT),"Go Left"); ChuThich.AddTool(GetDlgItem(IDC_COMMAND_RIGHT),"Go Right"); ChuThich.AddTool(GetDlgItem(IDC_COMMAND_CENTER),"Pause"); // B4 :Gán nội dung chú thích cho các đối tượng . …… UpdateData(FALSE); return TRUE; } BOOL CCNCControllerDlg::PreTranslateMessage(MSG* pMsg) { ChuThich.RelayEvent(pMsg); // B5: Relay để hiển thị chú thích. return(m_hAccel!=NULL)&&::TranslateAccelerator(m_hWnd,m_hAccel,pMsg); } -Tiếp theo sẽ tiến hành vẽ lên nền giao diện, giao diện trông có bắt mắt hay không thì cách trình bày phải gọn gàng và hợp lý .Hàm DrawGreen (CDC*pDC) sẽ thực hiện chức năng này. Trong hàm này , tham số chính là một thiết bị ngữ cảnh dùng để vẽ lên nền giao diện pDC, sau này nó sẽ được gọi trong hàm OnPaint ( ) và sẽ vẽ lên nền giao diện với khai báo một thiết bị ngữ cảnh khác nằm trong hàm OnPaint( ). void CCNCControllerDlg::DrawGreen(CDC*pDC) { CBrush Brush(RGB(255,255,255)); // Ở đây khai báo một bút tô Brush với màu là RGB với các tham số bên trong sẽ vẽ //lên nền giao diện màu trắng CBrush* OldBrush=pDC->SelectObject(&Brush); // Đặt bút vẽ lên chế độ hiện hành pDC->Rectangle(0,0,671,618); // Thiết bị ngữ cảnh pDC sẽ vẽ một khung chữ nhật với toạ độ (x,y ) của hai đỉnh đối //diện góc trên bên trái và góc dưới bên phải là (0,0) và (671,618). pDC->SelectObject(OldBrush); // Giải phóng bộ nhớ } Để giúp cho việc căn chỉnh các đối tượng hợp lý và để lấy được toạ độ của chuột trên nền giao diện có thể thêm một sự kiện WM_MOUSEMOVE với ObJect IDs là CNCControllerDlg : void CCNCControllerDlg::OnMouseMove(UINT nFlags, CPoint point) { Cstring ToaDoChuotX,ToaDoChuotY ; ToaDoChuotX.Format("%s",point.x); ToaDoChuotY.Format("%s",point.y); SetDlgItemText(IDC_STATIC_X,ToaDoChuotX); SetDlgItemText(IDC_STATIC_Y,ToaDoChuotY); UpdateData(FALSE); CDialog::OnMouseMove(nFlags, point); } Ở đây sẽ sử dụng đến 2 Static Text có ID là IDC_STATIC_X và IDC_STATIC_Y để lưu giữ toạ độ chuột, 2 Static Text này sẽ được đưa vào trong ứng dụng .Sau khi hoàn thành các công việc liên qua đến toạ độ chuột và không cần sử dụng chúng nữa có thể xoá nội dụng trong hàm OnMouseMove và hoàn toàn không ảnh hưởng gì đến cấu trúc chương trình. -Để viết các dòng chữ lên màn hình chúng ta tạo ra hàm WriteText(CDC*pDC) với nội dung như sau : void CCNCControllerDlg::WriteText(CDC*pDC) { CFont font; // Khai báo với hệ thống font CString str; //Str là chuỗi kí tự sẽ được viết lên màn hình font.CreateFont(20,0,0,0,600,0,0,0,ANSI_CHARSET,DEFAULT_CHARSET,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH,".VnArial"); //Nội dung của các tham số với hàm CreateFont có thể tham khảo ở chương 3, mục 1. CFont*pOldFont=pDC->SelectObject(&font); pDC->SetBkMode(TRANSPARENT); //Đặt nền cho dòng chữ này ở dạng trong suốt pDC->SetTextColor(RGB(0,0,255)); //Đặt nền cho chữ có mã RGB là 0,0,255. pDC->TextOut(25,231,m_strDichChuyen); //Sử dụng ngữ cảnh thiết bị để viết dòng chữ m_strDichChuyen với toạ độ của điểm //đỉnh góc trên bên trái là (25,231) pDC->SelectObject(pOldFont); CFont font1; font1.CreateFont(15,0,0,0,600,0,0,0,ANSI_CHARSET,DEFAULT_CHARSET, CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH,".VnTime"); CFont*pOldFont1=pDC->SelectObject(&font1); pDC->SetBkMode(TRANSPARENT); pDC->SetTextColor(RGB(0,0,0)); str="§ang ®äc file :"; //Viết dòng chữ Đang đọc File pDC->TextOut(304,252,str); str="G-Code"; pDC->TextOut(445,19,str); str="§iÒu khiÓn"; // Viết dòng chữ “Điều khiển” pDC->TextOut(95,19,str); str="Tr¹ng th¸i hiÖn t¹i"; //Dòng chữ “trạng thái hiện tại” pDC->TextOut(415,304,str); str="M« pháng gia c«ng"; // “Mô phỏng gia công” pDC->TextOut(415,360,str); str="Trôc Z "; // “Trục Z” pDC->TextOut(198,258,str); str="§iÒu khiÓn vÞ trÝ"; //Dòng chữ “Điều khiển vị trí” pDC->TextOut(95,488,str); str="Trôc X-Y"; // “Trục X-Y” pDC->TextOut(76,258,str); pDC->SelectObject(pOldFont1); CFont font2; font2.CreateFont(15,0,0,0,0,0,0,0,ANSI_CHARSET,DEFAULT_CHARSET, CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH,".Arial"); CFont*pOldFont2=pDC->SelectObject(&font2); pDC->SetBkMode(TRANSPARENT); pDC->SetTextColor(RGB(0,0,0)); str="X Axis :"; pDC->TextOut(310,330,str); str="Y Axis :"; pDC->TextOut(440,330,str); str="Z Axis :"; pDC->TextOut(564,330,str); } -Tiếp theo chúng ta sẽ tạo ra một vùng hiển thị (nằm trong khung của Picture đã được sử dụng lúc tạo giao diện) ,di chuột để lấy toạ độ của cặp đỉnh đối diện nhau và viết lệnh cho hàm KhungHienThi(CDC*pDC) , sau đó sẽ vẽ hệ toạ độ nhờ hàm DrawAxis(CDC*pDC) và vẽ dụng cụ cắt nhờ hàm DrawToolCut(CDC*pDC) : void CCNCControllerDlg::KhungHienThi(CDC*pDC) { CBrush Brush(RGB(111,234,227)); CBrush*OldBrush=pDC->SelectObject(&Brush); pDC->Rectangle(303,379,653,589); pDC->SelectObject(OldBrush); //Hàm này sẽ tô màu (có mã RGB là (111,234,227)lên hình chữ nhật có toạ độ cặp //đỉnh đối diện là (303,379) ;(653,589) . } void CCNCControllerDlg::DrawAxis(CDC*pDC) { int x,y; //Cặp x, y chính là tọa độ đỉnh được chọn làm mốc x=303; y=379; //(303,379);(653,589) CPen Pen(PS_SOLID,1,RGB(47,24,252)); // Khai báo một bút vẽ có kiểu PS_SOLID với độ dày là 1 và màu có mã RGB CPen*OldPen=pDC->SelectObject(&Pen); pDC->MoveTo(9+x,149+y); // Chuyển tới điểm có toạ độ 9+x, 149 +y. pDC->LineTo(9+x,190+y); // Từ điểm ban đầu vẽ đường thẳng tới điểm có toạ độ (9+x, 190+y) pDC->LineTo(49+x,190+y); pDC->LineTo(45+x,184+y); pDC->MoveTo(49+x,190+y); pDC->LineTo(45+x,196+y); pDC->MoveTo(9+x,149+y); pDC->LineTo(13+x,155+y); pDC->MoveTo(9+x,149+y); pDC->LineTo(5+x,155+y); pDC->SelectObject(&OldPen); CFont font; CString str; font.CreateFont(15,0,0,0,600,0,0,0,ANSI_CHARSET,DEFAULT_CHARSET, CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH,".VnArial"); CFont*pOldFont=pDC->SelectObject(&font); pDC->SetBkMode(TRANSPARENT); pDC->SetTextColor(RGB(0,0,128)); str="Y"; pDC->TextOut(4+x,130+y,str); str="O"; pDC->TextOut(4+x,191+y,str); str="X"; pDC->TextOut(50+x,191+y,str); pDC->SelectObject(pOldFont); } void CCNCControllerDlg::DrawToolCut(CDC *pDC, int xc, int yc, int r, COLORREF crColor) { CBrush *pBrush; CBrush *pOldBrush; pBrush=new CBrush(crColor); pOldBrush=pDC->SelectObject(pBrush); CRect rect(xc-r,yc-r,xc+r,yc+r); pDC->Ellipse(&rect); pDC->SelectObject(pOldBrush); } Các tham số của hàm vẽ dụng cụ cắt là một thiết bị ngữ cảnh thiết bị CDC*pDC, các toạ độ tâm xc, yc, bán kính r và màu được sử dụng để vẽ crColor. Thực ra các hàm liên quan đến vẽ màn hình đều có thể vẽ trực tiếp trong hàm OnPaint( ) với thiết bị ngữ cảnh duy nhất, tuy nhiên do tính phức tạp và để cho chương trình gọn gàng hơn nên viết chúng ra thành các hàm riêng biệt và khi cần thiết chỉ cần gọi lại chúng và truyền tham số cho chúng. Tất cả các hàm trên chỉ thực hiện là vẽ lên nền thiết bị ngữ cảnh được khai báo chứ không phải là thiết bị ngữ cảnh hiện hành và khi cho chạy chương trình chúng chẳng vẽ lên gì cả .Muốn sử dụng chúng lúc này ta gọi chúng trong hàm OnPaint( ) như sau : Trong CNCControllerDlg.cpp tìm đến hàm OnPaint( ) và thêm nội dung : void CCNCControllerDlg::OnPaint( ) { …………… else { CPaintDC dc(this); // Khai báo một thiết bị ngữ cảnh hiện hành sau đó gọi các hàm hiển thị với tham //số là thiết bị ngữ cảnh này DrawGreen(&dc); WriteText(&dc); KhungHienThi(&dc); DrawAxis(&dc); DrawToolCut(&dc,xc,yc,RTool,RGB(255,255,255)); CDialog::OnPaint( ); } } Lúc này cần phải khởi tạo giao diện khiến nó trở thành một Bitmap để có thể vẽ được lên đó, quay trở lại với hàm khởi tạo OnInitDialog( ) và thêm nội dung sau : BOOL CCNCControllerDlg::OnInitDialog( ) { CDialog::OnInitDialog( ); CRect CuaSoManHinh; GetClientRect(CuaSoManHinh); CClientDC dc(this); pCuaSoManHinh.CreateCompatibleDC(&dc); BCuaSo.CreateCompatibleBitmap(&dc, CuaSoManHinh.Width( ), CuaSoManHinh.Height( )); xc=478; yc=484; bufferyc=1.5; bufferxc=1.5; CSetToolDlg dlg; RTool=dlg.m_Radius; m_htToaDoXTool=0; m_htToaDoYTool=0; UpdateData(FALSE); return(TRUE); } -Viết code cho các nút bấm và tác vụ trên thanh Menu : các nút bấm ở đây đều sử dụng Active X nên không sử dụng sự kiện thông thường BN_CLICKED mà là sự kiện Click . Trên thanh menu có các tác vụ cũng giống như trên nút bấm nên thực chất chỉ cần viết code cho thanh menu sau đó sẽ gọi các hàm này trong sự kiện nút bấm .Thanh Menu File sẽ liên quan đến các tác vụ quản lý file văn bản : Ấn Ctrl +W, chọn lớp CNCControllerDlg, trong Object IDs chọn các ID liên quan đến menu (File, Action –Tool,Help) và trong ô Message chọn sự kiện COMMAND >Add Function >Ok : void CCNCControllerDlg::OnFileEditCode() { CEditCodeDlg dlgEdit; //Khai báo biến thuộc lớp EditCodeDlg. CString EditCode; //Chuỗi này sẽ lưu giữ nội dung được gõ trong Edit Box ở hộp thoại Edit Code EditCode=m_DieuKhienTextBox.GetText( ); // Hàm GetText( ) chỉ có trong lớp CmdcText là lớp quản lý Active X này dlgEdit.m_strEditCode=EditCode; // Chuyển nội dung trong TextBox hiển thị gán cho biến EditCode sau đó gán lại //cho Edit Box trong hộp thoại Edit Code if(dlgEdit.DoModal()==IDOK) { EditCode=dlgEdit.m_strEditCode; m_DieuKhienTextBox.SetText(EditCode); } // Tiến hành mở hộp thoại sau đó lấy nội dung đã được sửa đổi ở hộp thoại Edit //Code và trả lại hiển thị trên TextBox hiển thị nhờ hàm SetText thuộc lớp //CMdcText ThamSoTruyen=m_DieuKhienTextBox.GetText( ); UpdateData(FALSE); } Với ID_FILE_OPEN tác động sự kiện COMMAND : void CCNCControllerDlg::OnFileOpen( ) { FILE * FileDuocMo; char buffer[800001]; int ch,i; CString TenFile,TextBox; static char BASED_CODE szFilter[]="Text Files(*.txt)|*.txt|NC Files(*.nc)|*.nc|Rich Tech Format(*.RTF)|*.RTF|"; //Cho phép mở các file có định dạng “*.nc”, “*.RTF”, “*.txt” CFileDialog pFile(TRUE,"*.nc",DuongDanFile,OFN_HIDEREADONLY| OFN_OVERWRITEPROMPT,szFilter); // Mở hộp thoại Open nhờ tham số TRUE if (pFile.DoModal( )==IDOK) // Kiểm tra sự kiện có đồng ý mở file hay không { DuongDanFile=pFile.GetPathName( ); // Lấy đường dẫn đầy của file được chọn TenFile=pFile.GetFileName(); // Lấy tên đầy đủ của File if(DuongDanFile!="") // Kiểm tra Tên đường dẫn có là chuỗi rỗng hay không { if((FileDuocMo=fopen(DuongDanFile, "r"))= =NULL) exit( 0 ); ch = fgetc(FileDuocMo ); for( i=0; (i < 800001 ) && ( feof(FileDuocMo ) = = 0 ); i++ ) { buffer[i] = (char)ch; // lưu các kí tự trong file được mở và lưu vào một xâu kí tự ch = fgetc(FileDuocMo); } buffer[i] = '\0'; //Thêm Enter vào trong xâu kí tự ChuyenMaGCode(buffer); // Hàm này được gọi vào để chuyển nội dung file thành mã mô phỏng TextBox.Format( "%s\n", buffer ); m_DieuKhienTextBox.SetText(TextBox); //Hiển thị nội dung lên Text Box hiển thị fclose(FileDuocMo ); //Đóng file } } SetDlgItemText(IDC_STATIC_DANGDOCFILE,DuongDanFile); //Hiển thị tên đường dẫn file được mở lên static Text UpdateData(FALSE); // Cập nhật dữ liệu lên màn hình . } Với menu File- Save và Save As : void CCNCControllerDlg::OnFileSave( ) { ThamSoTruyen=m_DieuKhienTextBox.GetText( ); //Lưu nội dung trong Text Box hiển thị vào biến trung gian ThamSoTruyen FILE *File; CString str1; // Mở 1 file và ghi dữ liệu lên file if(DuongDanFile!="") { File=fopen(DuongDanFile,"w+r"); fputs(ThamSoTruyen,File); fclose(File); } UpdateData(FALSE); } void CCNCControllerDlg::OnFileSaveAs( ) { ThamSoTruyen=m_DieuKhienTextBox.GetText( ); CString TenFileSave; FILE *FileSave; static char BASED_CODE szFilter[]="Text Files(*.txt)|*.txt|NC Files(*.nc)|*.nc| Rich Tech Format(*.RTF)|*.RTF|"; CfileDialog pFile(FALSE,"*.nc",TenFileSave,OFN_HIDEREADONLY| OFN_OVERWRITEPROMPT,szFilter); if(pFile.DoModal( )==IDOK) { TenFileSave=pFile.GetFileName( ); DuongDanFileSave=pFile.GetPathName( ); if (TenFileSave!="") { CreateFile(TenFileSave, //Tên file được đặt ra GENERIC_READ | GENERIC_WRITE, //Tạo file có thể đọc ghi FILE_SHARE_READ|FILE_SHARE_WRITE, // Tính chia sẻ được NULL, // Không đặt chế độ bảo mật CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); } if(DuongDanFileSave!="") { FileSave=fopen(DuongDanFileSave,"w+r"); fputs(ThamSoTruyen,FileSave); fclose(FileSave); } } UpdateData(FALSE); } Viết code cho ID_FILE_EXIT : void CCNCControllerDlg::OnFileExit( ) { if(MessageBox("Do you want to exit from program", "Exit",MB_YESNO+MB_ICONQUESTION)==IDNO) return; else { OnOK( ); } } Viết code cho tác vụ trên menu Action -Configure : void CCNCControllerDlg::OnToolConfigure( ) { KillTimer(ID_CLOCK_RIGHT); KillTimer(ID_CLOCK_UP); KillTimer(ID_CLOCK_DOWN); KillTimer(ID_CLOCK_DOWNRIGHT); KillTimer(ID_CLOCK_DOWNLEFT); KillTimer(ID_CLOCK_UPLEFT); KillTimer(ID_CLOCK_UPRIGHT); KillTimer(ID_CLOCK_ANYPOINT); KillTimer(ID_CLOCK_LEFT); CConfigureDlg dlg; // Mở hộp thoại Configure và lưu các thông số vào các biến buffer if(dlg.DoModal()==IDOK) { bufferxc=dlg.m_ConfigureStepX; bufferyc=dlg.m_ConfigureStepY; bufferzc=dlg.m_ConfigureStepZ; bufferVelocity=dlg.m_ConfigureVelocity; UpdateData(FALSE); } } Các ID_CLOCK_... muốn sử dụng được phải được khai báo bằng cách tìm đến menu View trong cửa sổ VC ++ > ID= Resource Symbols >New đặt tên các ID như trong hàm trên . Với Action –Stop : void CCNCControllerDlg::OnToolStop( ) { //Tắt các bộ định thời để dừng mô phỏng KillTimer(ID_CLOCK_RIGHT); KillTimer(ID_CLOCK_DOWN); KillTimer(ID_CLOCK_LEFT); KillTimer(ID_CLOCK_DOWNRIGHT); KillTimer(ID_CLOCK_DOWNLEFT); KillTimer(ID_CLOCK_UPLEFT); KillTimer(ID_CLOCK_UPRIGHT); KillTimer(ID_CLOCK_UP); KillTimer(ID_CLOCK_ANYPOINT); // Làm vô hiệu lực các nút bấm nhờ hàm SetLocked( TRUE) là hàm trong //lớp quản lý Active X Command Button m_Up.SetLocked(TRUE); m_Down.SetLocked(TRUE); m_Left.SetLocked(TRUE); m_Right.SetLocked(TRUE); m_UpLeft.SetLocked(TRUE); m_UpRight.SetLocked(TRUE); m_Down.SetLocked(TRUE); m_DownLeft.SetLocked(TRUE); m_DownRight.SetLocked(TRUE); m_Zero.SetLocked(TRUE); m_UpZ.SetLocked(TRUE); m_DownZ.SetLocked(TRUE); m_Center.SetLocked(TRUE); m_Reset.SetLocked(TRUE); m_Configure.SetLocked(TRUE); UpdateData(FALSE); } Với Action –Run : void CCNCControllerDlg::OnToolRun( ) { //Làm các nút bấm điều khiển có hiệu lực. m_Up.SetLocked(FALSE); m_Down.SetLocked(FALSE); m_Left.SetLocked(FALSE); m_Right.SetLocked(FALSE); m_UpLeft.SetLocked(FALSE); m_UpRight.SetLocked(FALSE); m_Down.SetLocked(FALSE); m_DownLeft.SetLocked(FALSE); m_DownRight.SetLocked(FALSE); m_DownZ.SetLocked(FALSE); m_UpZ.SetLocked(FALSE); m_Center.SetLocked(FALSE); m_Reset.SetLocked(FALSE); m_Configure.SetLocked(FALSE); m_Zero.SetLocked(FALSE); m_Stop.SetLocked(FALSE); UpdateData(FALSE); } Viết code cho các nút bấm còn lại : Ở đây để mô phỏng ứng với từng điều khiển theo nút bấm , chúng ta sẽ dùng tới các bộ cài đặt thời gian, với mỗi điều khiển tương ứng với một bộ cài đặt thời gian, khi ấn mỗi nút điều khiển tương ứng với việc ngắt các bộ cài đặt thời gian khác và mở một bộ cài đặt thời gian của bản thân nó. void CCNCControllerDlg::OnClickCommandOpen( ) { OnFileOpen( ); } void CCNCControllerDlg::OnClickCommandEditCode( ) { OnFileEditCode( ); } void CCNCControllerDlg::OnClickCommandNew( ) { OnFileNew( ); } void CCNCControllerDlg::OnClickCommandSave( ) { OnFileSave( ); } void CCNCControllerDlg::OnClickCommandSaveAs( ) { OnFileSaveAs( ); } void CCNCControllerDlg::OnClickCommandConfigure( ) { OnToolConfigure( ); } void CCNCControllerDlg::OnClickCommandRun( ) { OnToolRun( ); } void CCNCControllerDlg::OnClickCommandStop( ) { OnToolStop( ); } void CCNCControllerDlg::OnClickCommandUpright( ) { KillTimer(ID_CLOCK_RIGHT); KillTimer(ID_CLOCK_DOWN); KillTimer(ID_CLOCK_LEFT); KillTimer(ID_CLOCK_DOWNRIGHT); KillTimer(ID_CLOCK_DOWNLEFT); KillTimer(ID_CLOCK_UPLEFT); KillTimer(ID_CLOCK_UPRIGHT); SetTimer(ID_CLOCK_UPRIGHT,300,NULL); KillTimer(ID_CLOCK_ANYPOINT); } void CCNCControllerDlg::OnClickCommandUpleft( ) { KillTimer(ID_CLOCK_RIGHT); KillTimer(ID_CLOCK_DOWN); KillTimer(ID_CLOCK_LEFT); KillTimer(ID_CLOCK_DOWNRIGHT); KillTimer(ID_CLOCK_DOWNLEFT); KillTimer(ID_CLOCK_UPLEFT); KillTimer(ID_CLOCK_UPRIGHT); KillTimer(ID_CLOCK_ANYPOINT); SetTimer(ID_CLOCK_UPLEFT,300,NULL); } void CCNCControllerDlg::OnClickCommandUp( ) { KillTimer(ID_CLOCK_RIGHT); KillTimer(ID_CLOCK_DOWN); KillTimer(ID_CLOCK_LEFT); KillTimer(ID_CLOCK_DOWNRIGHT); KillTimer(ID_CLOCK_DOWNLEFT); KillTimer(ID_CLOCK_UPLEFT); KillTimer(ID_CLOCK_UPRIGHT); KillTimer(ID_CLOCK_ANYPOINT); SetTimer(ID_CLOCK_UP,300,NULL); UpdateData(FALSE); } void CCNCControllerDlg::OnClickCommandRight( ) { KillTimer(ID_CLOCK_UP); KillTimer(ID_CLOCK_DOWN); KillTimer(ID_CLOCK_LEFT); KillTimer(ID_CLOCK_DOWNRIGHT); KillTimer(ID_CLOCK_DOWNLEFT); KillTimer(ID_CLOCK_UPLEFT); KillTimer(ID_CLOCK_UPRIGHT); KillTimer(ID_CLOCK_ANYPOINT); SetTimer(ID_CLOCK_RIGHT,300,NULL); } void CCNCControllerDlg::OnClickCommandLeft( ) { KillTimer(ID_CLOCK_UP); KillTimer(ID_CLOCK_DOWN); KillTimer(ID_CLOCK_RIGHT); KillTimer(ID_CLOCK_DOWNRIGHT); KillTimer(ID_CLOCK_DOWNLEFT); KillTimer(ID_CLOCK_UPLEFT); KillTimer(ID_CLOCK_UPRIGHT); KillTimer(ID_CLOCK_ANYPOINT); SetTimer(ID_CLOCK_LEFT,300,NULL); } void CCNCControllerDlg::OnClickCommandDownright( ) { KillTimer(ID_CLOCK_UP); KillTimer(ID_CLOCK_RIGHT); KillTimer(ID_CLOCK_LEFT); KillTimer(ID_CLOCK_DOWNLEFT); KillTimer(ID_CLOCK_UPLEFT); KillTimer(ID_CLOCK_UPRIGHT); KillTimer(ID_CLOCK_ANYPOINT); KillTimer(ID_CLOCK_DOWN); SetTimer(ID_CLOCK_DOWNRIGHT,300,NULL); } void CCNCControllerDlg::OnClickCommandDownleft( ) { KillTimer(ID_CLOCK_UP); KillTimer(ID_CLOCK_RIGHT); KillTimer(ID_CLOCK_LEFT); KillTimer(ID_CLOCK_DOWNRIGHT); KillTimer(ID_CLOCK_UPLEFT); KillTimer(ID_CLOCK_UPRIGHT); KillTimer(ID_CLOCK_DOWNLEFT); KillTimer(ID_CLOCK_DOWN); SetTimer(ID_CLOCK_DOWNLEFT,300,NULL); } void CCNCControllerDlg::OnClickCommandDown( ) { KillTimer(ID_CLOCK_UP); KillTimer(ID_CLOCK_RIGHT); KillTimer(ID_CLOCK_LEFT); KillTimer(ID_CLOCK_DOWNRIGHT); KillTimer(ID_CLOCK_DOWNLEFT); KillTimer(ID_CLOCK_UPLEFT); KillTimer(ID_CLOCK_UPRIGHT); KillTimer(ID_CLOCK_ANYPOINT); SetTimer(ID_CLOCK_DOWN,300,NULL); } void CCNCControllerDlg::OnClickCommandCenter( ) { KillTimer(ID_CLOCK_RIGHT); KillTimer(ID_CLOCK_UP); KillTimer(ID_CLOCK_DOWN); KillTimer(ID_CLOCK_LEFT); KillTimer(ID_CLOCK_DOWNRIGHT); KillTimer(ID_CLOCK_DOWNLEFT); KillTimer(ID_CLOCK_UPLEFT); KillTimer(ID_CLOCK_UPRIGHT); KillTimer(ID_CLOCK_ANYPOINT); } Với nút bấm SetTool :sẽ thực hiện các công việc là ngừng việc mô phỏng hiện thời và mở hộp thoại Tool Demension ,kiểm tra giá trị được nhập vào nếu vượt quá giới hạn sẽ hiển thị thông báo, nếu không vi phạm sẽ lấy các thông số để nạp vào chương trình chính . void CCNCControllerDlg::OnClickCommandSetTool( ) { // Cập nhật dữ liệu lên màn hình UpdateData(TRUE); // Dừng mô phỏng KillTimer(ID_CLOCK_RIGHT); KillTimer(ID_CLOCK_UP); KillTimer(ID_CLOCK_DOWN); KillTimer(ID_CLOCK_LEFT); KillTimer(ID_CLOCK_DOWNRIGHT); KillTimer(ID_CLOCK_DOWNLEFT); KillTimer(ID_CLOCK_UPLEFT); KillTimer(ID_CLOCK_UPRIGHT); KillTimer(ID_CLOCK_ANYPOINT); // Mở hộp thoại CSetToolDlg dlg; if (dlg.DoModal( )==IDOK) { if((1<=dlg.m_Radius)&&(dlg.m_Radius<=10)) { RTool=dlg.m_Radius; // Lưu thông số làm thông số cho dụng cụ cắt UpdateData(FALSE); } else // Hiển thị thông báo khi vượt quá giới hạn MessageBox("Choose Dimension of tool again :D !","Warning",MB_ICONWARNING+IDOK); } } Với nút bấm MPoint : đầu tiên cũng ngừng các hoạt động mô phỏng và lấy giá trị xuất phát ban đầu của dụng cụ cắt (thực ra là truyền tham số xc, yc mới cho hàm DrawToolCut ) hiển thị thông báo nếu như toạ độ được nhập vào vượt quá giá trị giới hạn là khung hiển thị . void CCNCControllerDlg::OnClickCommandZeropoint( ) { KillTimer(ID_CLOCK_RIGHT); KillTimer(ID_CLOCK_UP); KillTimer(ID_CLOCK_DOWN); KillTimer(ID_CLOCK_LEFT); KillTimer(ID_CLOCK_DOWNRIGHT); KillTimer(ID_CLOCK_DOWNLEFT); KillTimer(ID_CLOCK_UPLEFT); KillTimer(ID_CLOCK_UPRIGHT); KillTimer(ID_CLOCK_ANYPOINT); CDiemGocDlg dlg; if (dlg.DoModal()==IDOK) { if ((0<=dlg.m_ToolX)&&(dlg.m_ToolX<=330)&&(0<=dlg.m_ToolY) &&(dlg.m_ToolY<=200)) { xc=313+dlg.m_ToolX; yc=579-dlg.m_ToolY; } else { if(MessageBox("Over limited working region :D !", "Working Area",MB_ICONWARNING+MB_OK)= =IDOK) return; } } CClientDC dc(this); m_htToaDoXTool=xc-313; m_htToaDoYTool=579-yc; DrawAxis(&dc); DrawToolCut(&dc,xc,yc,RTool,RGB(255,255,255)); UpdateData(FALSE); } Nút bấm Reset : sẽ khởi động lại quá trình mô phỏng bằng cách ngắt các bộ cài đặt thời gian, khởi tạo dụng cụ cắt với thông số mặc định, xoá khung hiển thị và làm vô hiệu các nút điều khiển vị trí. void CCNCControllerDlg::OnClickCommandReset() { xc=478; yc=484; CClientDC dc(this); KhungHienThi(&dc); DrawAxis(&dc); DrawToolCut(&dc,xc,yc,RTool,RGB(255,255,255)); KillTimer(ID_CLOCK_RIGHT); KillTimer(ID_CLOCK_DOWN); KillTimer(ID_CLOCK_LEFT); KillTimer(ID_CLOCK_DOWNRIGHT); KillTimer(ID_CLOCK_DOWNLEFT); KillTimer(ID_CLOCK_UPLEFT); KillTimer(ID_CLOCK_UPRIGHT); KillTimer(ID_CLOCK_UP); KillTimer(ID_CLOCK_ANYPOINT); m_htToaDoXTool=0; m_htToaDoYTool=0; m_Up.SetLocked(TRUE); m_Down.SetLocked(TRUE); m_Left.SetLocked(TRUE); m_Right.SetLocked(TRUE); m_UpLeft.SetLocked(TRUE); m_UpRight.SetLocked(TRUE); m_Down.SetLocked(TRUE); m_DownLeft.SetLocked(TRUE); m_DownRight.SetLocked(TRUE); m_UpZ.SetLocked(TRUE); m_DownZ.SetLocked(TRUE); m_Zero.SetLocked(TRUE); UpdateData(FALSE); } Nút bấm To Any Point sẽ thực hiện mô phỏng quá trình gia công của dụng cụ cắt tới một vị trí nhất định, thực ra chỉ là quá trình nhập tham số, còn mô phỏng sẽ được thực hiện trong hàm OnTimer( ) : void CCNCControllerDlg::OnClickCommandToanypoint( ) { KillTimer(ID_CLOCK_RIGHT); KillTimer(ID_CLOCK_UP); KillTimer(ID_CLOCK_DOWN); KillTimer(ID_CLOCK_LEFT); KillTimer(ID_CLOCK_DOWNRIGHT); KillTimer(ID_CLOCK_DOWNLEFT); KillTimer(ID_CLOCK_UPLEFT); KillTimer(ID_CLOCK_UPRIGHT); KillTimer(ID_CLOCK_ANYPOINT); CToAnyPointDlg dlg; if (dlg.DoModal()= =IDOK) { m_ToX=dlg.m_ToX; m_ToY=dlg.m_ToY; m_buffer=dlg.m_Buffer; UpdateData(FALSE); } } Nút bấm Apply sẽ thực hiện nhiệm vụ là nhận các thông số từ hộp thoại To Any Point và đặt cho nó một SetTimer để quản lý : void CCNCControllerDlg::OnClickCommandApply( ) { KillTimer(ID_CLOCK_RIGHT); KillTimer(ID_CLOCK_UP); KillTimer(ID_CLOCK_DOWN); KillTimer(ID_CLOCK_LEFT); KillTimer(ID_CLOCK_DOWNRIGHT); KillTimer(ID_CLOCK_DOWNLEFT); KillTimer(ID_CLOCK_UPLEFT); KillTimer(ID_CLOCK_UPRIGHT); SetTimer(ID_CLOCK_ANYPOINT,300,NULL); } Công việc cuối cùng là sẽ mô phỏng quá trình gia công ứng với các nút điều khiển. Làm điều này thông qua các SetTimer( ) được đặt tương ứng với từng nút bấm . Tạo ra sự kiện OnTimer ấn Ctrl +W, chọn Object IDs là CNCControllerDlg và ô Message chọn WM_TIMER >Add Function >Edit Code : Thuật toán mô phỏng ở đây sẽ là dùng lượng tăng , giảm ΔX,ΔY sau một khoảng thời gian .Lượng tăng giảm này sẽ được gán cho tham số của hàm DrawToolCut chính là toạ độ xc,yc : xc ± =ΔX ; yc ± = ΔY; Khi mô phỏng quá trình gia công đến một vị trí bất kì từ điểm ban đầu ta làm như sau : gán toạ độ điểm ban đầu cho một biến trung gian để không làm ảnh hưởng đến các kết quả cố định. Tính khoảng cách từ điểm ban đầu tới điểm cuối cùng, tính góc hợp bởi phương nối hai điểm đầu và điểm cuối, lấy bước tiến từ hộp thoại To Any Point và tính ra bước tiến theo trục X, trục Y, sau đó gán cho toạ độ xc, yc những lượng tăng hay giảm . void CCNCControllerDlg::OnTimer(UINT nIDEvent) { CClientDC dc(this); //Vẽ lại các trục m_htToaDoXTool=xc-313; m_htToaDoYTool=579-yc; CPen Pen(PS_DASH,RTool,RGB(255,0,0)); CPen *OldPen=dc.SelectObject(&Pen); dc.MoveTo(xc,yc); switch(nIDEvent) { case ID_CLOCK_RIGHT: xc+=bufferxc; DrawToolCut(&dc,xc,yc,RTool,RGB(0,0,255)); dc.LineTo(xc,yc); break; case ID_CLOCK_UP: yc-=bufferyc; DrawToolCut(&dc,xc,yc,RTool,RGB(0,0,255)); dc.LineTo(xc,yc); break; case ID_CLOCK_DOWN: yc+=bufferyc; DrawToolCut(&dc,xc,yc,RTool,RGB(0,0,255)); dc.LineTo(xc,yc); break; case ID_CLOCK_LEFT: xc-=bufferxc; DrawToolCut(&dc,xc,yc,RTool,RGB(0,0,255)); dc.LineTo(xc,yc); break; case ID_CLOCK_DOWNRIGHT: yc+=bufferyc; xc+=bufferxc; DrawToolCut(&dc,xc,yc,RTool,RGB(0,0,255)); dc.LineTo(xc,yc); break; case ID_CLOCK_DOWNLEFT: yc+=bufferyc; xc-=bufferxc; DrawToolCut(&dc,xc,yc,RTool,RGB(0,0,255)); dc.LineTo(xc,yc); break; case ID_CLOCK_UPLEFT: yc-=bufferyc; xc-=bufferxc; DrawToolCut(&dc,xc,yc,RTool,RGB(0,0,255)); dc.LineTo(xc,yc); break; case ID_CLOCK_UPRIGHT: yc-=bufferyc; xc+=bufferxc; DrawToolCut(&dc,xc,yc,RTool,RGB(0,0,255)); dc.LineTo(xc,yc); break; case ID_CLOCK_ANYPOINT: double FromX,FromY,CosL,SinL,L,ToX,ToY,xbc,ybc,a,b; FromX=xc; FromY=yc; ToX=m_ToX+313; ToY=579-m_ToY; L=sqrt((ToX-FromX)*(ToX-FromX)+(ToY-FromY)*(ToY-FromY)); a=sqrt((ToX-FromX)*(ToX-FromX)); b=sqrt((ToY-FromY)*(ToY-FromY)); CosL=a/L; SinL=b/L; xbc=m_buffer*CosL; ybc=m_buffer*SinL; if((xc<=ToX)&&(yc<=ToY)&&(0<=xc)&&(0<=yc)) { xc+=xbc; yc+=ybc; DrawToolCut(&dc,xc,yc,RTool,RGB(0,0,255)); //dc.LineTo(xbc,ybc); UpdateData(FALSE); } if((xc>=ToX)&&(yc<=ToY)&&(0<=xc)&&(0<=yc)) { xc-=xbc; yc+=ybc; DrawToolCut(&dc,xc,yc,RTool,RGB(0,0,255)); //dc.LineTo(xc,yc); UpdateData(FALSE); } if ((xc>=ToX)&&(yc>=ToY)&&(0<=xc)&&(0<=yc)) { xc-=xbc; yc-=ybc; DrawToolCut(&dc,xc,yc,RTool,RGB(0,0,255)); //dc.LineTo(xc,yc); UpdateData(FALSE); } if ((xc=ToY)&&(0<=xc)&&(0<=yc)) { xc+=xbc; yc-=ybc; DrawToolCut(&dc,xc,yc,RTool,RGB(0,0,255)); //dc.LineTo(xc,yc); UpdateData(FALSE); } break; } DrawAxis(&dc); dc.SelectObject(&OldPen); if((xc>642)|(yc579)) { KillTimer(ID_CLOCK_RIGHT); KillTimer(ID_CLOCK_UP); KillTimer(ID_CLOCK_DOWN); KillTimer(ID_CLOCK_DOWNRIGHT); KillTimer(ID_CLOCK_DOWNLEFT); KillTimer(ID_CLOCK_UPLEFT); KillTimer(ID_CLOCK_UPRIGHT); KillTimer(ID_CLOCK_LEFT); KillTimer(ID_CLOCK_ANYPOINT); OnToolStop( ); if(MessageBox(" Over limited working are\nPlease choose start point again !", "Working Area",MB_ICONWARNING+MB_OK)= =IDOK) return; } CString DichChuyen; DichChuyen=m_strDichChuyen.Left(1); m_strDichChuyen.Delete(0.1); m_strDichChuyen=m_strDichChuyen+DichChuyen; InvalidateRect(CRect(26,230,240,257),TRUE); UpdateData(FALSE); CDialog::OnTimer(nIDEvent); } Viết Code cho hàm ChuyenMaGCode(char GCode[800001]) : void CCNCControllerDlg::ChuyenMaGCode(char GCode[800001]) { CString ss,ss1,ss2,str1;//Rm; int Dem=0,i=0;//,j,trunggian; //char s[1],s1[4],*s2=s1; while (GCode[Dem]!='\0')Dem++; for (i=0;i<=Dem;i++) { if ((GCode[i]= ='G')&&(GCode[i+1]= ='0')&&(GCode[i+2]= ='1')) { switch(GCode[i+4]) { case '0': m_ToX=0; ss1="0"; break; case '1': ss1="1"; m_ToX=1; break; case '2': ss1="2"; m_ToX=2; break; case '3': ss1="3"; m_ToX=3; break; case '4': ss1="4"; m_ToX=4; break; case '5': ss1="5"; m_ToX=5; break; case '6': ss1="6"; m_ToX=6; break; case '7': ss1="7"; m_ToX=7; break; case '8': ss1="8"; m_ToX=8; break; case '9': ss1="9"; m_ToX=9; break; } switch(GCode[i+6]) { case '0': ss2="0"; m_ToY=0; break; case '1': ss2="1"; m_ToY=1; break; case '2': ss2="2"; m_ToY=2; break; case '3': ss2="3"; m_ToY=3; break; case '4': ss2="4"; m_ToY=4; break; case '5': ss2="5"; m_ToY=5; break; case '6': ss2="6"; m_ToY=6; break; case '7': ss2="7"; m_ToY=7; break; case '8': ss2="8"; m_ToY=8; break; case '9': ss2="9"; m_ToY=9; break; } m_buffer=1; ss.Format("Ve Duong Thang X%s Y%s",ss1,ss2); OnClickCommandApply(); } } SetDlgItemText(IDC_STATIC12,ss); } ------------------------ HẾT---------------------- Tài liệu tham khảo [1]Tự học lập trình Visual C++ 6.0 –NXB Thống kê -Phạm Công Ngô (chủ biên) -Phạm Ngọc Nam -Phạm Tuấn Lượng [2]Ngôn ngữ lập trình C++ / -NXB thống kê - Quách Tuấn Ngọc. WebSites: - - - -

Các file đính kèm theo tài liệu này:

  • docHướng dẫn lập trình VC++ 60, mô phỏng điều khiển, gia công CNC.doc