M7第7話 補助線化

前話で作成した、水平・垂直・角度線を補助線として作図するようにします。前話のものでも、作図直前に補助線に指定して作図すれば補助線として作図出来ますが、いちいち元に戻す必要があります。補助線作図は、気楽にすばやく手間無く出来ないと意味がありません。基本的に、スナップと同じ感覚で使うのが常だからです。
 

 
M7では、補助線を描くには、まず、線分を通常のように作図をした後、属性変更(m7SetObjAttr)を行うという事のようです。カレント属性を補助線に変更してから作図、という事は、しないようです。
しかし、悲しいかな、どうしてもカレントペンNo.となってしまい、色が現在のペンNo.の色になってしまいます。画面を再描画すれば灰色で表示してくれますが・・・現在はちょっと、最初から灰色で表示する手法が分っていません。m(_ _)m
 

 
という訳で今回のプログラムは、↓ こんな感じ〜
 
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <m7.h>
 
/*
 水平線・垂直線・角度線を切り替えて補助線として描く
    by AF
*/
 
DPOINT lpos[2] ;  /* 始点座標、終点座標 */
int zukei ;     /* 図形 0:水平線 1:垂直線 2:角度線 */
double ang ;    /* 傾き角度 */
 
/********************************************/
/* ON_INITDLGメッセージハンドラ */
/********************************************/
int on_initdlg(HWND hwnd, int message, WPARAM wParam, LPARAM lParam){
 /*
  ** ここにダイアログの初期化に関する式を記入します。
  */
 m7CreateItem(hwnd, ITEM_STATIC , 0     ,  6, "X(&X)" , 0);
 m7CreateItem(hwnd, ITEM_EDIT  , IDC_EDIT1 , 20, ""   , 40);
 m7CreateItem(hwnd, ITEM_STATIC , 0     , 64, "Y(&Y)" , 0);
 m7CreateItem(hwnd, ITEM_EDIT  , IDC_EDIT2 , 80, ""   , 40);
 m7CreateItem(hwnd, ITEM_BUTTON , IDC_BUTTON1, 124, "Go(&G)", 30);
 m7CreateItem(hwnd, ITEM_RADIO , IDC_RADIO1 , 158, "水平線(&H)" , 1);
 m7CreateItem(hwnd, ITEM_RADIO , IDC_RADIO2 , 196, "垂直線(&V)" , 0);
 m7CreateItem(hwnd, ITEM_RADIO , IDC_RADIO3 , 234, "角度線(&A)" , 0);
 m7CreateItem(hwnd, ITEM_STATIC , 0     , 272, "傾き角度(&R)", 0);
 m7CreateItem(hwnd, ITEM_EDIT  , IDC_EDIT3 , 304, ""   , 40);
 return 0;
}
 
/********************************************/
/* ON_COMMANDメッセージハンドラ */
/********************************************/
int on_command(HWND hwnd, int message, WPARAM wParam, LPARAM lParam){
 /*
  ** ここにON_COMMANDメッセージの応答式を記入します。
  */
 double x[1];
 double y[1];
 double a[1];
 BYTE pplout,pptype;
 DPOINT psize[2];
 double cscale ;
 DPOINT pap[2] ; /* 用紙 最小座標・最大座標 */
 double l ;
 LPM7OBJ obj ;
 
 m7GetPaperType(&pplout,&pptype);
 m7GetPaperSize(psize);
 cscale = m7GetCurrentScale() ;
 if (cscale <= 0.0) {
  cscale = 1.0 ;
 }
 if (pplout == 0) {
  /* 図面横向き */
  pap[0].x = psize[0].x / cscale ;
  pap[0].y = psize[0].y / cscale ;
  pap[1].x = (psize[0].x + psize[1].x) / cscale ;
  pap[1].y = (psize[0].y + psize[1].y) / cscale ;
 }
 else {
  /* 図面縦向き */
  pap[0].x = psize[0].y / cscale ;
  pap[0].y = psize[0].x / cscale ;
  pap[1].x = (psize[0].y + psize[1].y) / cscale ;
  pap[1].y = (psize[0].x + psize[1].x) / cscale ;
 }
 m7GetItemAngles(hwnd, IDC_EDIT3, a, 1);
 ang = a[0] ;
 
 switch (wParam){
 case IDC_RADIO1: /* 水平線モード */
  zukei = 0;
  break;
 case IDC_RADIO2: /* 垂直線モード */
  zukei = 1;
  break;
 case IDC_RADIO3: /* 角度線モード */
  zukei = 2;
  break;
 case IDC_BUTTON1: /* ボタンを押した時の処理 */
  m7GetItemValues(hwnd, IDC_EDIT1, x, 1);
  m7GetItemValues(hwnd, IDC_EDIT2, y, 1);
  switch (zukei) {
  case 0:  /* 水平線 */
   lpos[0].x = pap[0].x ;
   lpos[0].y = y[0] ;
   lpos[1].x = pap[1].x ;
   lpos[1].y = y[0] ;
   break;
  case 1:  /* 垂直線 */
   lpos[0].x = x[0] ;
   lpos[0].y = pap[0].y ;
   lpos[1].x = x[0] ;
   lpos[1].y = pap[1].y ;
   break;
  case 2: /* 角度線 */
   l = (psize[1].x + psize[1].y) / 2.0 / cscale ;
   lpos[0].x = x[0] - l * cos(ang) ;
   lpos[0].y = y[0] - l * sin(ang) ;
   lpos[1].x = x[0] + l * cos(ang) ;
   lpos[1].y = y[0] + l * sin(ang) ;
   break;
  }
  m7StepObject();
  obj = m7MakeLineObject(lpos, M7OBJ_NORMAL);
  m7SetObjAttr(obj, M7ATTR_DEFLT, M7ATTR_DEFLT, MAKEATTR(M7_AUXLTYPE, 0));
  break;
 }
 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){
 /*
  ** ここにメソッドの初期化に関する式を記入します。
  */
 zukei = 0;
 ang = 0.0;
 m7SetProc(PROC_GETPOS);
 m7StatusText("通過点を指定して下さい", M7STS_NORMAL);
 return 0;
}
 
/********************************************/
/* ON_CLICKメッセージハンドラ */
/********************************************/
int on_click(HWND hwnd, int message, WPARAM wParam, LPARAM lParam){
 /*
  ** ここにマウスクリックに関する式を記入します。
  */
 DPOINT pos; // クリックした位置
 BYTE pplout,pptype;
 DPOINT psize[2];
 double cscale ;
 DPOINT pap[2] ; /* 用紙 最小座標・最大座標 */
 double l ;
 LPM7OBJ obj ;
 
 m7GetPaperType(&pplout,&pptype);
 m7GetPaperSize(psize);
 cscale = m7GetCurrentScale() ;
 if (cscale <= 0.0) {
  cscale = 1.0 ;
 }
 if (pplout == 0) {
  /* 図面横向き */
  pap[0].x = psize[0].x / cscale ;
  pap[0].y = psize[0].y / cscale ;
  pap[1].x = (psize[0].x + psize[1].x) / cscale ;
  pap[1].y = (psize[0].y + psize[1].y) / cscale ;
 }
 else {
  /* 図面縦向き */
  pap[0].x = psize[0].y / cscale ;
  pap[0].y = psize[0].x / cscale ;
  pap[1].x = (psize[0].y + psize[1].y) / cscale ;
  pap[1].y = (psize[0].x + psize[1].x) / cscale ;
 }
 
 pos = *(LPDPOINT)lParam; // lParamに位置が入っているので変数posに代入
 switch (zukei) {
 case 0: /* 水平線 */
  lpos[0].x = pap[0].x ;
  lpos[0].y = pos.y ;
  lpos[1].x = pap[1].x ;
  lpos[1].y = pos.y ;
  break;
 case 1: /* 垂直線 */
  lpos[0].x = pos.x ;
  lpos[0].y = pap[0].y ;
  lpos[1].x = pos.x ;
  lpos[1].y = pap[1].y ;
  break;
 case 2: /* 角度線 */
  l = (psize[1].x + psize[1].y) / 2.0 / cscale ;
  lpos[0].x = pos.x - l * cos(ang) ;
  lpos[0].y = pos.y - l * sin(ang) ;
  lpos[1].x = pos.x + l * cos(ang) ;
  lpos[1].y = pos.y + l * sin(ang) ;
  break;
 }
 m7StepObject();
 obj = m7MakeLineObject(lpos, M7OBJ_NORMAL);
 m7SetObjAttr(obj, M7ATTR_DEFLT, M7ATTR_DEFLT, MAKEATTR(M7_AUXLTYPE, 0));
 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){
 /*
  ** ここにアンドゥに関する式を記入します。
  */
 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);
}
 
 
C言語ソースファイルとアイコンBMPファイルを用意したら、「M7dev」で開いて、「ビルド」≫「ビルド」を行って、「ビルドは正常終了しました」と表示されたらOKです。「〜.m7p」というファイルが作成されます。これを「部品呼び出し」してみて下さい。