M7第1話 2点指定の線分

まずは、M7マクロを利用してコマンドを作成する手順を追って行こう!
M7マクロはC言語を利用しますので、まずはC言語についての知識が多少なりとも必要になるでしょう。って事で、C言語について何も知らない人は、ここに、昔テキトーにざっと書いたものがあるんで見てみてね! (^_^)
 

 
まずは「M7dev M7マクロ部品開発環境 v3.04」をインストールしましょう。するとWindowsの[スタート]メニューの中の「M7」グループ内に「M7dev」が追加されますので、これを動かします。
メニューの「ファイル」≫「新規作成」を行うと、以下のようなスケルトン(付属の default.c)が出来ますので、これに追記していきます。
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <m7.h>
 
/********************************************/
/* ON_INITDLGメッセージハンドラ */
/********************************************/
int on_initdlg(HWND hwnd, int message, WPARAM wParam, LPARAM lParam){
 /*
  ** ここにダイアログの初期化に関する式を記入します。
  */
 return 0;
}
 
/********************************************/
/* ON_COMMANDメッセージハンドラ */
/********************************************/
int on_command(HWND hwnd, int message, WPARAM wParam, LPARAM lParam){
 /*
  ** ここにON_COMMANDメッセージの応答式を記入します。
  */
 return 0;
}
 
/********************************************/
/* ON_CLOSEDLGメッセージハンドラ */
/********************************************/
int on_closedlg(HWND hwnd, int message, WPARAM wParam, LPARAM lParam){
 /*
  ** ここにダイアログの終了化に関する式を記入します。
  */
 return 0;
}
 
/********************************************/
/* ON_INITWNDメッセージハンドラ */
/********************************************/
int on_initwnd(HWND hwnd, int message, WPARAM wParam, LPARAM lParam){
 /*
  ** ここにメソッドの初期化に関する式を記入します。
  */
 return 0;
}
 
/********************************************/
/* ON_CLICKメッセージハンドラ */
/********************************************/
int on_click(HWND hwnd, int message, WPARAM wParam, LPARAM lParam){
 /*
  ** ここにマウスクリックに関する式を記入します。
  */
 return 0;
}
 
/********************************************/
/* ON_MOUSEMOVEメッセージハンドラ */
/********************************************/
int on_mousemove(HWND hwnd, int message, WPARAM wParam, LPARAM lParam){
 /*
  ** ここにマウスカーソル移動時の式を記入します。
  */
 return 0;
}
 
/********************************************/
/* ON_UNDOメッセージハンドラ */
/********************************************/
int on_undo(HWND hwnd, int message, WPARAM wParam, LPARAM lParam){
 /*
  ** ここにアンドゥに関する式を記入します。
  */
 return 0;
}
 
/********************************************/
/* ON_NOTIFYメッセージハンドラ */
/********************************************/
int on_notify(HWND hwnd, int message, WPARAM wParam, LPARAM lParam){
 /*
  ** ここに通知メッセージに関するコードを記入します。
  */
 return 0;
}
 
/********************************************/
/* ON_CLOSEWNDメッセージハンドラ */
/********************************************/
int on_closewnd(HWND hwnd, int message, WPARAM wParam, LPARAM lParam){
 /*
  ** ここにメソッドの終了化に関する式を記入します。
  */
 return 0;
}
 
/********************************************/
/* dialog proc 基本的に変更しません */
/********************************************/
int dlgproc(HWND hwnd, int message, WPARAM wParam, LPARAM lParam){
 
 switch (message){
  case ON_INITDLG:
   return on_initdlg(hwnd, message, wParam, lParam);
  case ON_COMMAND:
   return on_command(hwnd, message, wParam, lParam);
  case ON_CLOSEDLG:
   return on_closedlg(hwnd, message, wParam, lParam);
 }
 return 0;
}
 
/********************************************/
/* window proc 基本的に変更しません */
/********************************************/
int wndproc(HWND hwnd, int message, WPARAM wParam, LPARAM lParam){
 switch (message){
  case ON_INITWND:
   return on_initwnd(hwnd, message, wParam, lParam);
  case ON_CLICK:
   return on_click(hwnd, message, wParam, lParam);
  case ON_MOUSEMOVE:
   return on_mousemove(hwnd, message, wParam, lParam);
  case ON_UNDO:
   return on_undo(hwnd, message, wParam, lParam);
  case ON_NOTIFY:
   return on_notify(hwnd, message, wParam, lParam);
  case ON_CLOSEWND:
   return on_closewnd(hwnd, message, wParam, lParam);
 }
 return 0;
}
 
/********************************************/
/* main 基本的に変更しません */
/********************************************/
void main(void){
 m7DispatchProc(dlgproc, wndproc);
}
 
取りあえず、まずは、2点指定で線を作図するコマンドを作ってみましょう。
 
各メッセージハンドラは、以下の順番に実行されるようです。
ON_INITDLG → ON_INITWND → ・・・ → ON_CLOSEWND → ON_CLOSEDLG
グローバル変数の初期化などは、ON_INITWIND内で行えば良いようです。
ON_CLICKは、作図ウィンドウ上でマウスクリックした時に実行されますので、ここに、始点クリック処理・終点クリック処理を入れます。ON_MOUSEMOVEは、作図ウィンドウ上でマウス移動した時に実行されますので、終点クリック前に「エコー表示」=ラバーバンドの表示を行うようにします。ON_UNDOには、アンドゥの処理を入れます。それ以外は今回は必要ないです。
 
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <m7.h>
 
int smode ; /* Step Mode 0:始点指定 1:終点指定 */
DPOINT lpos[2] ; /* 始点座標、終点座標 */
 
/********************************************/
/* ON_INITDLGメッセージハンドラ */
/********************************************/
int on_initdlg(HWND hwnd, int message, WPARAM wParam, LPARAM lParam){
 /*
  ** ここにダイアログの初期化に関する式を記入します。
  */
 return 0;
}
 
/********************************************/
/* ON_COMMANDメッセージハンドラ */
/********************************************/
int on_command(HWND hwnd, int message, WPARAM wParam, LPARAM lParam){
 /*
  ** ここにON_COMMANDメッセージの応答式を記入します。
  */
 return 0;
}
 
/********************************************/
/* ON_CLOSEDLGメッセージハンドラ */
/********************************************/
int on_closedlg(HWND hwnd, int message, WPARAM wParam, LPARAM lParam){
 /*
  ** ここにダイアログの終了化に関する式を記入します。
  */
 return 0;
}
 
/********************************************/
/* ON_INITWNDメッセージハンドラ */
/********************************************/
int on_initwnd(HWND hwnd, int message, WPARAM wParam, LPARAM lParam){
 /*
  ** ここにメソッドの初期化に関する式を記入します。
  */
 smode = 0;
 m7SetProc(PROC_GETPOS);
 m7StatusText("始点を指定して下さい", M7STS_NORMAL);
 return 0;
}
 
/********************************************/
/* ON_CLICKメッセージハンドラ */
/********************************************/
int on_click(HWND hwnd, int message, WPARAM wParam, LPARAM lParam){
 /*
  ** ここにマウスクリックに関する式を記入します。
  */
 DPOINT pos; // クリックした位置
 pos = *(LPDPOINT)lParam; // lParamに位置が入っているので変数posに代入
 switch(smode) {
  case 0:   // 始点処理→終点処理へ
   lpos[0] = pos ;
   m7StatusText("終点を指定して下さい", M7STS_NORMAL);
   smode = 1;
   break;
  case 1:   // 終点処理→線分作図→始点処理へ
   lpos[1] = pos ;
   m7StepObject();
   m7MakeLineObject(lpos, M7OBJ_NORMAL);
   m7StatusText("始点を指定して下さい", M7STS_NORMAL);
   smode = 0;
   break;
 }
 return 0;
}
 
/********************************************/
/* ON_MOUSEMOVEメッセージハンドラ */
/********************************************/
int on_mousemove(HWND hwnd, int message, WPARAM wParam, LPARAM lParam){
 /*
  ** ここにマウスカーソル移動時の式を記入します。
  */
 DPOINT pos[2]; // クリックした位置
 switch(smode) {
  case 1:   // 終点を指定しようとしている時:エコー表示
   pos[0] = lpos[0] ;
   pos[1] = *(LPDPOINT)lParam;
   m7DrawLine(pos);
   break;
 }
 return 0;
}
 
/********************************************/
/* ON_UNDOメッセージハンドラ */
/********************************************/
int on_undo(HWND hwnd, int message, WPARAM wParam, LPARAM lParam){
 /*
  ** ここにアンドゥに関する式を記入します。
  */
 m7UndoObject();
 return 0;
}
 
/********************************************/
/* ON_NOTIFYメッセージハンドラ */
/********************************************/
int on_notify(HWND hwnd, int message, WPARAM wParam, LPARAM lParam){
 /*
  ** ここに通知メッセージに関するコードを記入します。
  */
 return 0;
}
 
/********************************************/
/* ON_CLOSEWNDメッセージハンドラ */
/********************************************/
int on_closewnd(HWND hwnd, int message, WPARAM wParam, LPARAM lParam){
 /*
  ** ここにメソッドの終了化に関する式を記入します。
  */
 return 0;
}
 
/********************************************/
/* dialog proc 基本的に変更しません */
/********************************************/
int dlgproc(HWND hwnd, int message, WPARAM wParam, LPARAM lParam){
 
 switch (message){
  case ON_INITDLG:
   return on_initdlg(hwnd, message, wParam, lParam);
  case ON_COMMAND:
   return on_command(hwnd, message, wParam, lParam);
  case ON_CLOSEDLG:
   return on_closedlg(hwnd, message, wParam, lParam);
 }
 return 0;
}
 
/********************************************/
/* window proc 基本的に変更しません */
/********************************************/
int wndproc(HWND hwnd, int message, WPARAM wParam, LPARAM lParam){
 switch (message){
  case ON_INITWND:
   return on_initwnd(hwnd, message, wParam, lParam);
  case ON_CLICK:
   return on_click(hwnd, message, wParam, lParam);
  case ON_MOUSEMOVE:
   return on_mousemove(hwnd, message, wParam, lParam);
  case ON_UNDO:
   return on_undo(hwnd, message, wParam, lParam);
  case ON_NOTIFY:
   return on_notify(hwnd, message, wParam, lParam);
  case ON_CLOSEWND:
   return on_closewnd(hwnd, message, wParam, lParam);
 }
 return 0;
}
 
/********************************************/
/* main 基本的に変更しません */
/********************************************/
void main(void){
 m7DispatchProc(dlgproc, wndproc);
}
 
コードを入力したら、取りあえずまず、ファイルを保存しましょう。そして、メニューの「ビルド」≫「ビルド」を行って、「ビルドは正常終了しました」と表示されたらOKです。「〜.m7p」というファイルが作成されます。これを「部品呼び出し」してみて下さい。
 
DPOINT型は、座標を扱う変数を宣言する時に使います。「DPOINT p;」と宣言すると、「p.x」(X座標)「p.y」(Y座標)という変数が使える構造体のようです。
「m7SetProc(PROC_GETPOS);」は、これから作図ウインドウ上で位置入力をします、という事を指示します。「m7StatusText()」はステータスバーにメッセージ表示をするのに使います。
ON_CLICK、OB_MOUSEMOVE時に
  「DPOINT pos;
   pos = *(LPDPOINT)lParam;」
と記述すると、変数 pos 内にマウス位置が入るようです。
「m7StepObject()」は、作図直前に呼び出す事によって、アンドゥに対応させる事が出来ます。「m7MakeLineObject()」は、線の作図登録を行います。
「m7DrawLine()」は、線のエコー表示を行います。この関数では線の登録は行われません。一時的に線を表示したい時に使われるようです。
「m7UndoObject()」を呼び出すと、M7で「アンドゥ(元に戻す)」をして直前に作図した図形を削除する事が出来るようになります。