ChildView.cpp

C:\home\SVGCats_src\src\ChildView.cpp

[目次 | 関数 | マクロ]

目次

関数一覧

マクロ一覧


   1|// ChildView.cpp : CChildView クラスの動作の定義を行います。 
   2|//
   3|
   4|#include "mixer_precomp.h"
   5|
   6|#ifdef  USES_MXP_AUTOINC
   7| #include  "SVGCat.ah"
   8|#endif
   9|
  10|#include <ddraw.h>
  11|#include <imm.h>
  12|#define  InkRedraw
  13|
  14|
  15|#ifdef _DEBUG
  16|#define new DEBUG_NEW
  17|#undef THIS_FILE
  18|static char THIS_FILE[] = __FILE__;
  19|#endif
  20|
  21|static char*  _image_filter="画像ファイル(*.jpg;*.gif;*.png)|*.jpg;*.gif;*.png|すべてのファイル (*.*)|*.*||";
  22|static char*  _image_filterE="Image File (*.jpg;*.gif;*.png)|*.jpg;*.gif;*.png|All Files (*.*)|*.*||";
  23|char*  _DefaultFont;
  24|
  25|/////////////////////////////////////////////////////////////////////////////
  26|// CChildView
  27|
  28|CChildView::CChildView()
  29|{
  30|  m_InkTablets = NULL;
  31|  m_RopePoints = (POINT*)malloc( CChildView_RopeMPoint * sizeof(POINT) );
  32|  m_RopeNPoint = -1;
  33|  m_bEnableOnPaint = true;
  34|  m_bFirstPainted = false;
  35|  m_bDisableSwapRec = false;
  36|}
  37|
  38|IMPLEMENT_DYNCREATE(CChildView, CScrollView)
  39|
  40|BEGIN_MESSAGE_MAP(CChildView,CScrollView )
  41|	//{{AFX_MSG_MAP(CChildView)
  42|	ON_WM_CREATE()
  43|	ON_WM_PAINT()
  44|	ON_COMMAND(ID_Print, OnPrint)
  45|	ON_WM_SIZE()
  46|	ON_WM_ERASEBKGND()
  47|	ON_WM_SETCURSOR()
  48|	ON_WM_LBUTTONDOWN()
  49|	ON_WM_LBUTTONUP()
  50|	ON_WM_MOUSEMOVE()
  51|	ON_WM_LBUTTONDBLCLK()
  52|	ON_WM_RBUTTONDOWN()
  53|	ON_WM_RBUTTONUP()
  54|	ON_WM_RBUTTONDBLCLK()
  55|	ON_COMMAND(ID_SelectAll, OnSelectAll)
  56|	ON_COMMAND(ID_DragCopy, OnDragCopy)
  57|	ON_COMMAND(ID_DragMove, OnDragMove)
  58|	ON_COMMAND(ID_DragCancel, OnDragCancel)
  59|	ON_COMMAND(ID_EDIT_UNDO, OnEditUndo)
  60|	ON_COMMAND(ID_EDIT_REDO, OnEditRedo)
  61|	ON_COMMAND(ID_RetKey, OnRetKey)
  62|	ON_COMMAND(ID_SpcKey, OnSpcKey)
  63|	ON_COMMAND(ID_ZBottom, OnZBottom)
  64|	ON_COMMAND(ID_ZDown, OnZDown)
  65|	ON_COMMAND(ID_ZTop, OnZTop)
  66|	ON_COMMAND(ID_ZUp, OnZUp)
  67|	ON_COMMAND(ID_PrimDown, OnPrimDown)
  68|	ON_COMMAND(ID_PrimLeft, OnPrimLeft)
  69|	ON_COMMAND(ID_PrimRight, OnPrimRight)
  70|	ON_COMMAND(ID_PrimUp, OnPrimUp)
  71|	ON_COMMAND(ID_Zoom, OnZoom)
  72|	ON_COMMAND(ID_Zoom100, OnZoom100)
  73|	ON_COMMAND(ID_Zoom200, OnZoom200)
  74|	ON_COMMAND(ID_Zoom400, OnZoom400)
  75|	ON_COMMAND(ID_Zoom800, OnZoom800)
  76|	ON_COMMAND(ID_ZoomWhole, OnZoomWhole)
  77|	ON_COMMAND(ID_ZoomWidth, OnZoomWidth)
  78|	ON_COMMAND(ID_ZoomSwap, OnZoomSwap)
  79|	ON_COMMAND(ID_ZoomIn, OnZoomIn)
  80|	ON_COMMAND(ID_ZoomOut, OnZoomOut)
  81|	ON_COMMAND(ID_CatchGrid, OnCatchGrid)
  82|	ON_COMMAND(ID_DisplayGrid, OnDisplayGrid)
  83|	ON_UPDATE_COMMAND_UI(ID_CatchGrid, OnUpdateCatchGrid)
  84|	ON_UPDATE_COMMAND_UI(ID_DisplayGrid, OnUpdateDisplayGrid)
  85|	ON_COMMAND(ID_SetStdGrid, OnSetStdGrid)
  86|	ON_COMMAND(ID_SetPageButton, OnSetPageButton)
  87|	ON_WM_MOUSEWHEEL()
  88|	ON_WM_TIMER()
  89|	ON_COMMAND(ID_DEL, OnDel)
  90|	ON_COMMAND(ID_NextPageScroll, OnNextPageScroll)
  91|	ON_COMMAND(ID_PrevPageScroll, OnPrevPageScroll)
  92|	//}}AFX_MSG_MAP
  93|	ON_COMMAND(ID_SetPropMulti, OnSetPropMulti)
  94|END_MESSAGE_MAP()
  95|
  96|
  97|/////////////////////////////////////////////////////////////////////////////
  98|// CChildView メッセージ ハンドラ
  99|
 100|
 101| 
 102|/***********************************************************************
 103|  1. <<< [CChildView::PreCreateWindow] ウィンドウを生成する前の初期化処理 >>> 
 104|************************************************************************/
 105|BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs)
 106|{
 107|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
 108|  char  path[_MAX_PATH];
 109|
 110|	if (!CScrollView::PreCreateWindow(cs))
 111|		return FALSE;
 112|
 113|	cs.dwExStyle |= WS_EX_CLIENTEDGE;
 114|	cs.style &= ~WS_BORDER;
 115|	cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS,
 116|		::LoadCursor(NULL, IDC_ARROW), HBRUSH(COLOR_WINDOW+1), NULL);
 117|
 118|  m_ClickUpTime1 = 0;
 119|  m_ClickUpTime2 = 0;
 120|  m_MsgToDragScroller = 0;
 121|  m_DragScroller = CreateThread( NULL, 0,
 122|         (LPTHREAD_START_ROUTINE)CChildView_DragScroller, this, 0, NULL );
 123|  m_MsgToBlinker = 0;
 124|  m_Blinker = NULL;
 125|  m_bWhiteToBGColor = false;
 126|  m_MinusOffset.x = 0;  m_MinusOffset.y = 0;
 127|  m_bExistOutOfCanvas = false;
 128|  m_bPrinting = false;
 129|  m_Zoom = 100;
 130|  m_ZoomNext = 100;
 131|  m_ZoomMode = CChildView_ZoomNormal;
 132|  m_ZoomSwitchZoom = 100;
 133|  m_ZoomSwitchOffset.x = 0;  m_ZoomSwitchOffset.y = 0;
 134|  m_ZoomSwitchMode = CChildView_ZoomNormal;
 135|  m_ZoomSwitchPage = 1;
 136|  m_bBitmap = FALSE;
 137|  m_BitmapWidth = 0;  m_BitmapHeight = 0;
 138|  m_Bitmap = NULL;
 139|  #ifdef  SVGCAT_USES_BACKBUF
 140|  m_bBackBitmap = false;
 141|  #endif
 142|  WinX_DDBmp_init( &m_HatchedCanvas, _work_path "\\hatched.ddb" );
 143|  StrX_getExeFullPath( m_HatchedCanvas.path, m_HatchedCanvas.path, sizeof(m_HatchedCanvas.path) );
 144|  m_bDrag = FALSE;
 145|  m_bDblDrag = FALSE;
 146|  m_bSelectedClick = FALSE;
 147|  m_bInDragPlay = FALSE;
 148|  m_bDragGrided = FALSE;
 149|  m_bRightDrag = false;
 150|  m_bRightMenuAble = false;
 151|  m_PrevCanvasHeight = -1;
 152|  m_InputML = NULL;
 153|  m_bCreate = FALSE;
 154|  m_bFirstCreate = FALSE;
 155|  m_HoldPrim = NULL;
 156|  #ifdef  USES_INK
 157|    m_HoldInk = NULL;
 158|  #endif
 159|  m_BeforePrim = NULL;
 160|  m_Editor = new Text_Editor;
 161|  m_iHoldHandle = 0;
 162|  m_Cursor = LoadCursor( NULL, IDC_ARROW );
 163|  m_TextCreateX = 30;
 164|  m_TextCreateY = 30;
 165|  m_bEditorEnable = false;
 166|  ListX_init( &m_MultiHolds );
 167|  ListX_init( &m_MultiBefore );
 168|  ListX_init( &m_MultiSelects );
 169|  m_PrimRightMenu = GetSubMenu( LoadMenu( app->m_hInstance,
 170|    app->m_bJapanese ? MAKEINTRESOURCE(IDR_PrimRight) : MAKEINTRESOURCE(IDR_PrimRight_E) ), 0 );
 171|  m_DragMenu = GetSubMenu( LoadMenu( app->m_hInstance,
 172|    app->m_bJapanese ? MAKEINTRESOURCE(IDR_DragMenu) : MAKEINTRESOURCE(IDR_DragMenu_E) ), 0 );
 173|  StrX_getExeFullPath( path, "system\\plugin", sizeof(path) );
 174|  Susies_init( &Susies_globl, path );
 175|  SetScrollSizes( MM_TEXT, CSize(10, 10), CSize(10,10), CSize(10,10) );
 176|
 177|  m_MinBitmap = NULL;
 178|
 179|  _DefaultFont = ( app->m_bJapanese ? "MS Pゴシック" : "Arial" );
 180|
 181|  return TRUE;
 182|}
 183|
 184|
 185| 
 186|/***********************************************************************
 187|  2. <<< [CChildView::OnCreate] ウィンドウを生成した後の初期化処理 >>> 
 188|************************************************************************/
 189|int CChildView::OnCreate(LPCREATESTRUCT lpCreateStruct)
 190|{
 191|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
 192|  CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
 193|
 194|  if (CScrollView ::OnCreate(lpCreateStruct) == -1)
 195|    return -1;
 196|
 197|
 198|  /* メンバ変数の初期化 */
 199|  Variant_initEmpty( &m_PointsOnStroke );
 200|  m_HoldStrokes = NULL;
 201|  m_bHitInk = false;
 202|  m_DrawingStroke = NULL;
 203|  m_bRightTap = false;
 204|
 205|  CClientDC  dc(this);
 206|  HRESULT  hr;
 207|
 208|  DDSURFACEDESC ddsd;
 209|
 210|  if ( ! m_bFirstPainted ) {
 211|    /* 以下を OnPaint に持っていくと、m_MinBitmapDC が Create される前に
 212|       CSVGCatApp::InitInstance - CMainFrame::Load - Text_Box::Draw -
 213|       CDC::SaveDC が呼ばれるためエラーになる */
 214|    m_BitmapDC.CreateCompatibleDC( &dc );
 215|    m_MinBitmapDC.CreateCompatibleDC( &dc );
 216|    #ifdef  SVGCAT_USES_BACKBUF
 217|      m_BackBitmapDC.CreateCompatibleDC( &dc );
 218|    #endif
 219|  }
 220|
 221|#ifdef USES_InkPicture
 222|  RECT rc;
 223|  SetRect( &rc,0,0,500,300);
 224|  m_InkPicture.Create( NULL, WS_CHILD | WS_VISIBLE, rc, this, 15000 );
 225|  m_InkPicture.SetBackColor( RGB(0xFF,0xFF,0xFF) );
 226|  m_InkPicture.ShowWindow( SW_HIDE );
 227|#endif
 228|
 229|  /* DirecrDrawオブジェクトの生成 */
 230|  hr = DirectDrawCreate( NULL, &m_ddraw, NULL );
 231|  if ( hr != DD_OK ) error();
 232|  hr = m_ddraw->SetCooperativeLevel( m_hWnd, DDSCL_NORMAL );
 233|  if ( hr != DD_OK ) error();
 234|
 235|  ZeroMemory( &ddsd, sizeof( ddsd ) );
 236|  ddsd.dwSize = sizeof( ddsd );
 237|  ddsd.dwFlags = DDSD_CAPS;
 238|  ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOMEMORY;
 239|  hr = m_ddraw->CreateSurface( &ddsd, &m_priSurf, NULL );
 240|  if ( hr != DD_OK )  m_priSurf = NULL;
 241|
 242|  #if 1
 243|  if ( m_priSurf == NULL )  m_backSurf = NULL;
 244|  else {
 245|    ZeroMemory( &ddsd, sizeof( ddsd ) );
 246|    ddsd.dwSize = sizeof( ddsd );
 247|    ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
 248|    ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
 249|    ddsd.dwWidth = dc.GetDeviceCaps( HORZRES );
 250|    ddsd.dwHeight = dc.GetDeviceCaps( VERTRES );
 251|    hr = m_ddraw->CreateSurface( &ddsd, &m_backSurf, NULL );
 252|    if ( hr != DD_OK )  m_backSurf = NULL;
 253|  }
 254|  #else
 255|  m_backSurf = NULL;
 256|  #endif
 257|
 258|
 259|  /* キャレットを点滅させるスレッドを起動させる */
 260|  m_Blinker = CreateThread( NULL, 0,
 261|         (LPTHREAD_START_ROUTINE)CChildView_Blinker, this, 0, NULL );
 262|
 263|
 264|  /* タブレット情報オブジェクトを生成する */
 265|  hr = CoCreateInstance( CLSID_InkTablets, NULL, CLSCTX_INPROC_SERVER,
 266|                         IID_IInkTablets, (void**)&m_InkTablets );
 267|  if ( hr == CChildView_Err_NoTabletModule )  m_InkTablets = NULL;
 268|  else if ( hr != 0 )  error();
 269|
 270|
 271|  /* インクを描く領域を生成する */
 272|  m_InkOverlay = NULL;
 273|  NewInkOverlay();
 274|
 275|
 276|  if ( m_InkOverlay != NULL ) {
 277|
 278|
 279|    /* インクを描く領域のサイズを生成する */
 280|    hr = CoCreateInstance( CLSID_InkRectangle, NULL, CLSCTX_INPROC_SERVER,
 281|                           IID_IInkRectangle, (void**)&m_InkRectangle );
 282|    if ( hr != 0 )  error();
 283|
 284|    hr = m_InkRectangle->SetRectangle( /*top*/ 0, /*left*/ 0,
 285|      /*bottom*/ app->m_file.m_Canvas.m_Height * m_Zoom / 100, /*right*/ app->m_file.m_Canvas.m_Width * m_Zoom / 100 );
 286|    if ( hr != 0 )  error();
 287|
 288|    m_InkOverlay->SetWindowInputRectangle( m_InkRectangle );
 289|    if ( hr != 0 )  error();
 290|
 291|    m_prevX0 = 0;  m_prevY0 = 0;
 292|    m_prevScrollPos.x = 0;  m_prevScrollPos.y = 0;
 293|    m_prevZoom = 100;
 294|
 295|
 296|    /* 描画属性を生成する */
 297|    hr = CoCreateInstance( CLSID_InkDrawingAttributes, NULL, CLSCTX_INPROC_SERVER,
 298|                           IID_IInkDrawingAttributes, (void**)&m_PenAttr );
 299|    if ( hr != 0 )  error();
 300|
 301|    hr = m_PenAttr->put_Width( 38 );
 302|    if ( hr != 0 )  error();
 303|    hr = m_PenAttr->put_Height( 38 );
 304|    if ( hr != 0 )  error();
 305|    hr = m_PenAttr->put_Color( RGB(0,0,0) );
 306|    if ( hr != 0 )  error();
 307|    hr = m_PenAttr->put_IgnorePressure( VARIANT_FALSE );
 308|    if ( hr != 0 )  error();
 309|
 310|
 311|    hr = CoCreateInstance( CLSID_InkDrawingAttributes, NULL, CLSCTX_INPROC_SERVER,
 312|                           IID_IInkDrawingAttributes, (void**)&m_RedPenAttr );
 313|    if ( hr != 0 )  error();
 314|
 315|    hr = m_RedPenAttr->put_Width( 38 );
 316|    if ( hr != 0 )  error();
 317|    hr = m_RedPenAttr->put_Height( 38 );
 318|    if ( hr != 0 )  error();
 319|    hr = m_RedPenAttr->put_Color( RGB(0xFF,0,0) );
 320|    if ( hr != 0 )  error();
 321|    hr = m_RedPenAttr->put_IgnorePressure( VARIANT_FALSE );
 322|    if ( hr != 0 )  error();
 323|
 324|
 325|    hr = CoCreateInstance( CLSID_InkDrawingAttributes, NULL, CLSCTX_INPROC_SERVER,
 326|                           IID_IInkDrawingAttributes, (void**)&m_BluePenAttr );
 327|    if ( hr != 0 )  error();
 328|
 329|    hr = m_BluePenAttr->put_Width( 38 );
 330|    if ( hr != 0 )  error();
 331|    hr = m_BluePenAttr->put_Height( 38 );
 332|    if ( hr != 0 )  error();
 333|    hr = m_BluePenAttr->put_Color( RGB(0,0,0xFF) );
 334|    if ( hr != 0 )  error();
 335|    hr = m_BluePenAttr->put_IgnorePressure( VARIANT_FALSE );
 336|    if ( hr != 0 )  error();
 337|
 338|
 339|    hr = CoCreateInstance( CLSID_InkDrawingAttributes, NULL, CLSCTX_INPROC_SERVER,
 340|                           IID_IInkDrawingAttributes, (void**)&m_MarkerAttr );
 341|    if ( hr != 0 )  error();
 342|
 343|    hr = m_MarkerAttr->put_Width( 50 );
 344|    if ( hr != 0 )  error();
 345|    // hr = m_MarkerAttr->put_Height( 400 );
 346|    hr = m_MarkerAttr->put_Width( 400 );  // IPT_Ball では、Height が無視される
 347|    if ( hr != 0 )  error();
 348|    hr = m_MarkerAttr->put_Color( RGB(0xA8,0xFF,0x60) );
 349|    if ( hr != 0 )  error();
 350|    hr = m_MarkerAttr->put_RasterOperation( IRO_MaskPen );
 351|    if ( hr != 0 )  error();
 352|    hr = m_MarkerAttr->put_IgnorePressure( VARIANT_TRUE );
 353|    if ( hr != 0 )  error();
 354|  //  hr = m_MarkerAttr->put_PenTip( IPT_Rectangle );
 355|  //  if ( hr != 0 )  error();
 356|    // IPT_Rectangle(線の方向に関係なく縦横指定) は、SVG では無理? なのでやめ
 357|
 358|
 359|    hr = CoCreateInstance( CLSID_InkDrawingAttributes, NULL, CLSCTX_INPROC_SERVER,
 360|                           IID_IInkDrawingAttributes, (void**)&m_RedMarkerAttr );
 361|    if ( hr != 0 )  error();
 362|
 363|    hr = m_RedMarkerAttr->put_Width( 50 );
 364|    if ( hr != 0 )  error();
 365|    // hr = m_MarkerAttr->put_Height( 400 );
 366|    hr = m_RedMarkerAttr->put_Width( 400 );  // IPT_Ball では、Height が無視される
 367|    if ( hr != 0 )  error();
 368|    hr = m_RedMarkerAttr->put_Color( RGB(0xFF,0x40,0xD0) );
 369|    if ( hr != 0 )  error();
 370|    hr = m_RedMarkerAttr->put_RasterOperation( IRO_MaskPen );
 371|    if ( hr != 0 )  error();
 372|    hr = m_RedMarkerAttr->put_IgnorePressure( VARIANT_TRUE );
 373|    if ( hr != 0 )  error();
 374|  //  hr = m_RedMarkerAttr->put_PenTip( IPT_Rectangle );
 375|  //  if ( hr != 0 )  error();
 376|
 377|
 378|    hr = CoCreateInstance( CLSID_InkDrawingAttributes, NULL, CLSCTX_INPROC_SERVER,
 379|                           IID_IInkDrawingAttributes, (void**)&m_YellowMarkerAttr );
 380|    if ( hr != 0 )  error();
 381|
 382|    hr = m_YellowMarkerAttr->put_Width( 50 );
 383|    if ( hr != 0 )  error();
 384|    // hr = m_MarkerAttr->put_Height( 400 );
 385|    hr = m_YellowMarkerAttr->put_Width( 400 );  // IPT_Ball では、Height が無視される
 386|    if ( hr != 0 )  error();
 387|    hr = m_YellowMarkerAttr->put_Color( RGB(0xFF,0xFF,0x40) );
 388|    if ( hr != 0 )  error();
 389|    hr = m_YellowMarkerAttr->put_RasterOperation( IRO_MaskPen );
 390|    if ( hr != 0 )  error();
 391|    hr = m_YellowMarkerAttr->put_IgnorePressure( VARIANT_TRUE );
 392|    if ( hr != 0 )  error();
 393|  //  hr = m_YellowMarkerAttr->put_PenTip( IPT_Rectangle );
 394|  //  if ( hr != 0 )  error();
 395|
 396|
 397|    hr = CoCreateInstance( CLSID_InkDrawingAttributes, NULL, CLSCTX_INPROC_SERVER,
 398|                           IID_IInkDrawingAttributes, (void**)&m_SelectPenAttr );
 399|    if ( hr != 0 )  error();
 400|
 401|    hr = m_SelectPenAttr->put_Width( 1 );
 402|    if ( hr != 0 )  error();
 403|    hr = m_SelectPenAttr->put_Height( 1 );
 404|    if ( hr != 0 )  error();
 405|    // hr = m_SelectPenAttr->put_RasterOperation( IRO_XOrPen );
 406|    hr = m_SelectPenAttr->put_RasterOperation( IRO_NoOperation );
 407|    if ( hr != 0 )  error();
 408|    hr = m_SelectPenAttr->put_Color( RGB(0xFF,0,0) );
 409|    if ( hr != 0 )  error();
 410|
 411|
 412|    m_bMyInkSelectMode = false;
 413|
 414|
 415|    /* 文字認識パネルを生成する */
 416|    hr = CoCreateInstance( CLSID_PenInputPanel, NULL, CLSCTX_INPROC_SERVER,
 417|                           IID_IPenInputPanel, (void**)&m_PenInputPanel );
 418|    if ( hr != 0 )  m_PenInputPanel = NULL;  /* Tablet PC でないときは、失敗する */
 419|    m_bInputML_bDispPenPanel = ( hr == 0 );
 420|  }
 421|
 422|  return 0;
 423|}
 424|
 425|
 426| 
 427|/***********************************************************************
 428|  3. <<< [CChildView::NewInkOverlay] InkOverlay を新規作成するか作り直す >>> 
 429|************************************************************************/
 430|void  CChildView::NewInkOverlay()
 431|{
 432|  HRESULT  hr;
 433|  IInkDisp*  ink;
 434|  bool  bResetAttr = ( m_InkOverlay != NULL );
 435|  VARIANT_BOOL  bEnable = VARIANT_FALSE;
 436|  CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
 437|
 438|  if ( m_InkOverlay != NULL ) {
 439|    #ifndef NDEBUG
 440|      int  nInk = GetInkCount();
 441|    #endif
 442|
 443|    hr = m_EmptyStrokes->Release();
 444|    hr = m_Ink->Release();  m_Ink = NULL;
 445|
 446|    /* IInkDisp::Load できるように、削除する */
 447|    hr = m_InkOverlay->get_Enabled( &bEnable );
 448|    if ( hr != 0 )  error();
 449|
 450|    hr = m_InkOverlay->get_Ink( &ink );
 451|    if ( hr != 0 )  error();
 452|
 453|    ink->DeleteStrokes( NULL );
 454|    if ( hr != 0 )  error();
 455|
 456|    ink->put_Dirty( VARIANT_FALSE );
 457|    if ( hr != 0 )  error();
 458|
 459|    hr = ink->Release();  ink = NULL;
 460|
 461|    //ASSERT( nInk == GetInkCount() );
 462|
 463|    delete  m_InkEvents;
 464|
 465|    hr = m_InkOverlay->Release();  m_InkOverlay = NULL;
 466|    if ( hr != 0 )  error();
 467|  }
 468|
 469|
 470|  #if  ERRORS_DEBUG_FALSE  /* Tablet PC モジュールがないときのテスト用 */
 471|    if ( m_InkTablets != NULL )  m_InkTablets->Release();
 472|    m_InkTablets = NULL;
 473|    m_InkOverlay = NULL;
 474|    m_InkRectangle = NULL;
 475|    m_PenInputPanel = NULL;
 476|    return;
 477|  #endif
 478|
 479|  {
 480|    CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
 481|
 482|    if ( app->m_bNoInkForDebug ) {
 483|      if ( m_InkTablets != NULL )  m_InkTablets->Release();
 484|      m_InkTablets = NULL;
 485|      m_InkOverlay = NULL;
 486|      m_InkRectangle = NULL;
 487|      m_PenInputPanel = NULL;
 488|      return;
 489|    }
 490|  }
 491|
 492|
 493|  /* インクを描く領域を生成する */
 494|  hr = CoCreateInstance( CLSID_InkOverlay, NULL, CLSCTX_INPROC_SERVER,
 495|                         IID_IInkOverlay, (void**)&m_InkOverlay );
 496|              /* ここでなぜか、画面全体をリフレッシュする */
 497|  if ( hr == CChildView_Err_NoTabletModule )  m_InkOverlay = NULL;
 498|  else if ( hr != 0 )  error();
 499|
 500|  if ( m_InkOverlay == NULL )   return;
 501|
 502|  hr = m_InkOverlay->put_hWnd( (DWORD)m_hWnd );
 503|  if ( hr != 0 )  error();
 504|
 505|  hr = m_InkOverlay->put_AutoRedraw( VARIANT_FALSE );
 506|  if ( hr != 0 )  error();
 507|
 508|  hr = m_InkOverlay->put_AttachMode( IOAM_Behind );
 509|  if ( hr != 0 )  error();
 510|
 511|  hr = m_InkOverlay->put_Enabled( bEnable );
 512|  if ( hr != 0 )  error();
 513|
 514|
 515|  switch ( frame->m_mode ) {
 516|    case  CMainFrame_UseInk:     frame->OnInk();  break;
 517|    case  CMainFrame_UseRedInk:  frame->OnRedInk();  break;
 518|    case  CMainFrame_UseBlueInk: frame->OnBlueInk();  break;
 519|    case  CMainFrame_UseMarker:  frame->OnMarker();  break;
 520|    case  CMainFrame_UseRedMarker:  frame->OnRedMarker();  break;
 521|    case  CMainFrame_UseYellowMarker:  frame->OnYellowMarker();  break;
 522|    case  CMainFrame_UseRope:    frame->OnRope();  break;
 523|  }
 524|
 525|
 526|  /* イベントを受け取るオブジェクトを生成する */
 527|  m_InkEvents = new InkOverlayEvents;
 528|
 529|  hr = m_InkEvents->Init();
 530|  if ( hr != 0 )  error();
 531|
 532|  hr = m_InkOverlay->SetEventInterest( ICEI_AllEvents, VARIANT_FALSE );
 533|  if ( hr != 0 )  error();
 534|
 535|  hr = m_InkOverlay->SetEventInterest( ICEI_Stroke, VARIANT_TRUE );
 536|  if ( hr != 0 )  error();
 537|
 538|  hr = m_InkOverlay->SetEventInterest( ICEI_NewPackets, VARIANT_TRUE );  /* ストロークの頂点 */
 539|  if ( hr != 0 )  error();
 540|
 541|  hr = m_InkOverlay->SetEventInterest( ICEI_CursorDown, VARIANT_TRUE );  /* 右タップ */
 542|  if ( hr != 0 )  error();
 543|
 544|  hr = m_InkOverlay->SetEventInterest( ICEI_SystemGesture, VARIANT_TRUE );  /* 右タップ */
 545|  if ( hr != 0 )  error();
 546|
 547|  hr = m_InkEvents->AdviseInkOverlay( m_InkOverlay );
 548|  if ( hr != 0 )  error();
 549|
 550|  m_InkEvents->m_obj = this;
 551|
 552|
 553|  /* 空の Strokes を取得する(CoCreateInstance ではできないため) */
 554|  hr = m_InkOverlay->get_Ink( &m_Ink );  if ( hr != S_OK )  error();
 555|  hr = m_Ink->HitTestCircle( INT_MIN, INT_MIN, 0.0f, &m_EmptyStrokes ); if ( hr != S_OK )  error();
 556|
 557|
 558|  /* 座標系がリセットされるので、それに合わせる */
 559|  m_prevX0 = 0;  m_prevY0 = 0;  m_prevScrollPos.x = 0;  m_prevScrollPos.y = 0;
 560|  m_prevZoom = 100;
 561|}
 562|
 563|
 564| 
 565|/***********************************************************************
 566|  4. <<< [CChildView::OnClose2] 後始末 >>> 
 567|************************************************************************/
 568|void CChildView::OnClose2()
 569|{
 570|  ListX_ElemX*  p;
 571|
 572|  m_MsgToDragScroller = 1;
 573|  m_MsgToBlinker = 1;
 574|  WaitForSingleObject( m_DragScroller, INFINITE );
 575|  CloseHandle( m_DragScroller );
 576|
 577|  Variant_finish( &m_PointsOnStroke );
 578|  if ( m_InkOverlay != NULL ) {
 579|    if ( m_HoldStrokes != NULL )  { m_HoldStrokes->Release();  m_HoldStrokes = NULL; }
 580|    if ( m_PenInputPanel != NULL )  { m_PenInputPanel->Release();  m_PenInputPanel = NULL; }
 581|    if ( m_PenAttr != NULL )  { m_PenAttr->Release();  m_PenAttr = NULL; }
 582|    if ( m_RedPenAttr != NULL )  { m_RedPenAttr->Release();  m_RedPenAttr = NULL; }
 583|    if ( m_BluePenAttr != NULL )  { m_BluePenAttr->Release();  m_BluePenAttr = NULL; }
 584|    if ( m_MarkerAttr != NULL )  { m_MarkerAttr->Release();  m_MarkerAttr = NULL; }
 585|    if ( m_RedMarkerAttr != NULL )  { m_RedMarkerAttr->Release();  m_RedMarkerAttr = NULL; }
 586|    if ( m_SelectPenAttr != NULL )  { m_SelectPenAttr->Release();  m_SelectPenAttr = NULL; }
 587|
 588|    if ( m_InkRectangle != NULL )  { m_InkRectangle->Release();  m_InkRectangle = NULL; }
 589|    if ( m_InkEvents != NULL )  { delete  m_InkEvents;  m_InkEvents = NULL; }
 590|  }
 591|  if ( m_InkOverlay != NULL )  { m_InkOverlay->Release();  m_InkOverlay = NULL; }
 592|  if ( m_InkTablets != NULL )  { m_InkTablets->Release();  m_InkTablets = NULL; }
 593|
 594|  if ( m_backSurf != NULL )  m_backSurf->Release();
 595|  if ( m_priSurf != NULL )  m_priSurf->Release();
 596|  if ( m_ddraw != NULL )  m_ddraw->Release();
 597|
 598|  delete  m_Bitmap;   m_Bitmap = NULL;
 599|  m_BitmapDC.DeleteDC();
 600|  WinX_DDBmp_finish( &m_HatchedCanvas );
 601|  delete  m_MinBitmap;  m_MinBitmap = NULL;
 602|  m_MinBitmapDC.DeleteDC();
 603|  #ifdef  SVGCAT_USES_BACKBUF
 604|  if ( m_bBackBitmap ) {
 605|    delete  m_BackBitmap;  m_BackBitmap = NULL;
 606|    m_BackBitmapDC.DeleteDC();
 607|    WinX_DDBmp_finish( &m_BackBmp );
 608|  }
 609|  #endif
 610|
 611|  ListX_finish2( &m_MultiHolds, ListX_ElemX, NULL );
 612|  m_HoldPrim = NULL;
 613|  ListX_finish2( &m_MultiSelects, ListX_ElemX, NULL );
 614|  for ( ListX_forEach( &m_MultiBefore, &p, ListX_ElemX ) )
 615|    delete  (CadPrim*)p->p;
 616|  ListX_finish2( &m_MultiBefore, ListX_ElemX, NULL );
 617|  if ( m_BeforePrim != NULL )  delete  m_BeforePrim;
 618|  Susies_finish( &Susies_globl );
 619|  delete  m_Editor;
 620|
 621|  free( m_RopePoints );
 622|}
 623|
 624|
 625| 
 626|/***********************************************************************
 627|  5. <<< [CChildView_saveOnEditing] 自動バックアップする >>> 
 628|************************************************************************/
 629|void  CChildView_saveOnEditing( CChildView* m, CInputML* dlg )
 630|{
 631|  CSVGCatApp*   app = (CSVGCatApp*)AfxGetApp();
 632|  CMainFrame*  frame = (CMainFrame*)m->GetParent()->GetParent();
 633|error();
 634|
 635|  dlg->save();
 636|  ((Text_Box*)m->m_HoldPrim)->m_Text = dlg->m_Text;
 637|
 638|  if ( app->m_path[0] == '\0' ) {
 639|    frame->SaveAsImp( NULL, false );
 640|  }
 641|  else {
 642|    m->Redraw( true );
 643|    app->Save( app->m_path, false );
 644|  }
 645|}
 646| 
 647|/***********************************************************************
 648|  6. <<< [CChildView_saveOnEditing1] 自動バックアップする >>> 
 649|************************************************************************/
 650|void  CChildView_saveOnEditing1( CChildView* m, CInputML1* dlg )
 651|{
 652|  CSVGCatApp*   app = (CSVGCatApp*)AfxGetApp();
 653|  CMainFrame*  frame = (CMainFrame*)m->GetParent()->GetParent();
 654|
 655|  dlg->save();
 656|  ((Text_Box*)m->m_HoldPrim)->m_Text = dlg->m_Text;
 657|
 658|  if ( app->m_path[0] == '\0' ) {
 659|    frame->SaveAsImp( NULL, false );
 660|  }
 661|  else {
 662|    m->Redraw( true );
 663|    app->Save( app->m_path, false );
 664|  }
 665|}
 666| 
 667|/***********************************************************************
 668|  7. <<< [CChildView::OnTimer] ドラッグ中のタイマーイベントハンドラ >>> 
 669|************************************************************************/
 670|void CChildView::OnTimer( UINT nIDEvent )
 671|{
 672|  switch ( nIDEvent ) {
 673|    case  CMainFrame_Timer_DragScroll:
 674|      OnDragScrollTiming();
 675|      break;
 676|  }
 677|	CScrollView ::OnTimer(nIDEvent);
 678|}
 679| 
 680|/***********************************************************************
 681|  8. <<< [CChildView::OutInkSVG] インクの座標を SVG に出力する >>> 
 682|【補足】
 683|・Tablet PC SDK の InkOverlay object を参考。
 684|・InkOverlayビュー以下の構成は、次のとおり。
 685|  IInkOverlay - Ink - Strokes … Stroke - VARIANT(long型配列)
 686|  IInkOverlay - Renderer
 687|・Tablet PC SDK v1.5 では、CChildView::InInkSVG で行っているストロークの
 688|  追加が連続でできないため、SVG ファイルの中に、特殊なインクデータを
 689|  埋め込んでいます。
 690|************************************************************************/
 691|void  CChildView::OutInkSVG( FILE* f, InkRasterOperation outRaster )
 692|{
 693|  IInkDisp* ink;
 694|  IInkStrokes*  strokes;
 695|  IInkStrokeDisp* stroke;
 696|  IInkRenderer*  rend;
 697|  IInkTablet*  tablet;
 698|  VARIANT  points;
 699|  VARIANT  weights;
 700|  HRESULT  hr;
 701|  VARIANT_BOOL  bPress;
 702|  VARIANT_BOOL  bIgnorePress;
 703|  VARIANT  pressureName;
 704|  int   iStroke;
 705|  long  i;
 706|  long  n;
 707|  enum InkPenTip  tip;
 708|  InkRasterOperation  ras;
 709|  float  baseW;
 710|  long  x, y, x0, y0, w = 22;
 711|  VARIANT  rawInkData;
 712|  const WCHAR*  wp;
 713|  char*  cp;
 714|  int  cp_size;
 715|  #ifndef NDEBUG
 716|    int  nInk = GetInkCount();
 717|  #endif
 718|
 719|  if ( m_InkOverlay == NULL )  return;
 720|
 721|  hr = m_InkOverlay->get_Ink( &ink );
 722|  if ( hr != 0 )  error();
 723|
 724|  hr = ink->get_Strokes( &strokes );
 725|  if ( hr != 0 )  error();
 726|
 727|  hr = strokes->get_Count( &x );
 728|  if ( hr != 0 )  error();
 729|  if ( x == 0 )  {
 730|    hr = strokes->Release();  strokes = NULL;
 731|    hr = ink->Release();  ink = NULL;
 732|    return;
 733|  }
 734|
 735|  Variant_initEmpty( &points );
 736|  Variant_initEmpty( &weights );
 737|  Variant_initEmpty( &rawInkData );
 738|
 739|  hr = m_InkOverlay->get_Renderer( &rend );
 740|  if ( hr != 0 )  error();
 741|
 742|  Variant_initBSTR( &pressureName, STR_GUID_NORMALPRESSURE );
 743|
 744|  hr = rend->Move( m_prevX0, m_prevY0 );
 745|  if ( hr != 0 ) error();
 746|
 747|  hr = rend->ScaleTransform( (float)100 / m_Zoom, (float)100 / m_Zoom );
 748|  if ( hr != 0 ) error();
 749|
 750|  fprintf( f, "\t<g id=\"svgcats-ink\" type=\"%s\">\n",
 751|    outRaster == IRO_CopyPen ? "front" : "back" );
 752|  for ( iStroke = 0; ; iStroke ++ ) {
 753|    strokes->Item( iStroke, &stroke );
 754|    if ( stroke == NULL )  break;
 755|
 756|    hr = stroke->GetPoints( 0, -1, &points );
 757|    if ( hr == TPC_E_INVALID_STROKE )  continue;
 758|    if ( hr != S_OK )  error();
 759|
 760|    SafeArrayGetLBound( points.parray, 1, &x );
 761|    SafeArrayGetUBound( points.parray, 1, &y );
 762|    n = (y - x + 1) / 2;
 763|
 764|    hr = m_InkTablets->get_DefaultTablet( &tablet );
 765|    if ( hr != S_OK )  error();
 766|
 767|    /* ストロークの描画属性を取得する */
 768|    hr = stroke->GetPacketValuesByProperty( Variant_refBSTR( &pressureName ), 0, -1, &weights );
 769|    if ( hr == S_OK )  bPress = true;
 770|    else if ( hr == E_INVALIDARG )  bPress = false;
 771|    else
 772|      error();
 773|    hr = stroke->get_DrawingAttributes( &m_WorkDrawAttr );
 774|    if ( hr != 0 )  error();
 775|    hr = m_WorkDrawAttr->get_Color( &i );
 776|    if ( hr != 0 )  error();
 777|    hr = m_YellowMarkerAttr->get_PenTip( &tip );
 778|    if ( hr != 0 )  error();
 779|    if ( tip == IPT_Rectangle )  hr = m_WorkDrawAttr->get_Height( &baseW );
 780|    else  hr = m_WorkDrawAttr->get_Width( &baseW );
 781|    if ( hr != 0 )  error();
 782|    hr = m_WorkDrawAttr->get_IgnorePressure( &bIgnorePress );
 783|    if ( hr != 0 )  error();
 784|    hr = m_WorkDrawAttr->get_RasterOperation( &ras );
 785|    if ( hr != 0 )  error();
 786|
 787|    if ( ras != outRaster )  goto to_continue;
 788|
 789|    fprintf( f, "\t<g id=\"svgcats-stroke\" style=\"stroke:rgb(%d,%d,%d);stroke-linecap:%s",
 790|      Color_WinRGB_getR( i ), Color_WinRGB_getG( i ), Color_WinRGB_getB( i ),
 791|      "round" /*tip == IPT_Rectangle ? "butt" : "round"*/  /* butt では線の間ができてしまう */
 792|    );
 793|
 794|    if ( outRaster != IRO_CopyPen )
 795|      fputs( ";stroke-opacity:0.30;fill-opacity:0.0", f );
 796|
 797|    fputs( "\">\n", f );
 798|
 799|    w = 17 * (long)baseW / 53;
 800|
 801|
 802|    if ( outRaster == IRO_CopyPen ) {
 803|      for ( i = 0; i < n*2; i+=2 ) {
 804|
 805|        /* 座標を取得する */
 806|        SafeArrayGetElement( points.parray, &i, &x );
 807|        i++;
 808|        SafeArrayGetElement( points.parray, &i, &y );
 809|        i--;
 810|        x *= 10;  y *= 10;
 811|        rend->InkSpaceToPixel( (long)m_BitmapDC.m_hDC, &x, &y );
 812|
 813|        /* 太さを取得する */
 814|        if ( bPress && ! bIgnorePress ) {
 815|          i /= 2;
 816|          SafeArrayGetElement( weights.parray, &i, &w );
 817|          i *= 2;
 818|          w = (long)( w * baseW / 310 );
 819|        }
 820|
 821|        /* SVG ファイルに出力する */
 822|        if ( i != 0 ) {
 823|          fprintf( f, "\t<line x1=\"%d.%d\" y1=\"%d.%d\" x2=\"%d.%d\" y2=\"%d.%d\"\n",
 824|            x0 / 10, x0 % 10, y0 / 10, y0 % 10, x / 10, x % 10, y / 10, y % 10 );
 825|
 826|          fprintf( f, "\t\tstyle=\"stroke-width:%d.%d\"/>\n", w/10, w%10 );
 827|
 828|          x0 = ( x < x0 ) ? x+3 : x-3;
 829|          y0 = ( y < y0 ) ? y+3 : y-3;
 830|        }
 831|        else {
 832|          x0 = x;
 833|          y0 = y;
 834|        }
 835|      }
 836|    }
 837|    else {
 838|      for ( i = 0; i < n*2; i+=2 ) {
 839|
 840|        /* 座標を取得する */
 841|        SafeArrayGetElement( points.parray, &i, &x );
 842|        i++;
 843|        SafeArrayGetElement( points.parray, &i, &y );
 844|        i--;
 845|        x *= 10;  y *= 10;
 846|        rend->InkSpaceToPixel( (long)m_BitmapDC.m_hDC, &x, &y );
 847|
 848|        /* 太さを取得する */
 849|        if ( bPress && ! bIgnorePress ) {
 850|          i /= 2;
 851|          SafeArrayGetElement( weights.parray, &i, &w );
 852|          i *= 2;
 853|          w = (long)( w * baseW / 310 );
 854|        }
 855|
 856|        /* SVG ファイルに出力する */
 857|        if ( i != 0 ) {
 858|          if ( abs(x0-x)+abs(y0-y) > 50 ) {
 859|            fprintf( f, "\t<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\"\n",
 860|              x0 / 10, y0 / 10, x / 10, y / 10 );
 861|
 862|            fprintf( f, "\t\tstyle=\"stroke-width:%d.%d\"/>\n", w/10, w%10 );
 863|            x0 = x;
 864|            y0 = y;
 865|          }
 866|        }
 867|        else {
 868|          x0 = x;
 869|          y0 = y;
 870|        }
 871|      }
 872|    }
 873|    fputs( "\t</g>\n", f );
 874|
 875|  to_continue:
 876|    hr = m_WorkDrawAttr->Release();  m_WorkDrawAttr = NULL;
 877|    if ( hr > 5 )  error();
 878|    hr = tablet->Release();  tablet = NULL;
 879|    if ( hr > 5 )  error();
 880|    hr = stroke->Release();  stroke = NULL;
 881|    if ( hr > 5 )  error();
 882|    Variant_finish( &weights );
 883|    Variant_finish( &points );
 884|  }
 885|  Variant_finish( &pressureName );
 886|
 887|  hr = rend->ScaleTransform( (float)m_Zoom / 100, (float)m_Zoom / 100 );
 888|  if ( hr != 0 ) error();
 889|  hr = rend->Move( -m_prevX0, -m_prevY0 );
 890|  if ( hr != 0 ) error();
 891|
 892|
 893|  /* 生のインクデータを出力する(ストロークを追加できない SDKの制限?を回避) */
 894|  if ( outRaster == IRO_CopyPen ) {
 895|    hr = ink->Save( IPF_Base64InkSerializedFormat, IPCM_NoCompression, &rawInkData );
 896|    if ( hr != S_OK )  error();
 897|
 898|    n = Variant_getStrlen( &rawInkData );
 899|    wp = Variant_refWCharP( &rawInkData );
 900|    cp_size = n * 74 / 73 + 1;
 901|    cp = (char*)malloc( cp_size );
 902|    for ( i = 0; i < n; i++ )
 903|      cp[i] = (char)wp[i];
 904|    StrX_separateByByteInLine( cp, cp_size, 74, "\n" );
 905|
 906|    fprintf( f, "<svgcats-ink-rawdata>\n<![CDATA[\n" );
 907|    fwrite( cp, 1, strlen(cp), f );
 908|    fprintf( f, "\n]]>\n</svgcats-ink-rawdata>\n" );
 909|    free( cp );
 910|
 911|    Variant_finish( &rawInkData );
 912|  }
 913|
 914|  Variant_finish( &points );
 915|  Variant_finish( &weights );
 916|
 917|  hr = strokes->Release();  strokes = NULL;
 918|  if ( hr > 5 )  error();
 919|  hr = rend->Release();  rend = NULL;
 920|  if ( hr > 5 )  error();
 921|  hr = ink->Release();  ink = NULL;
 922|  // if ( hr > 5 )  error();  // ロープを使っているときは増えるのでチェックしない
 923|
 924|  fprintf( f, "\t</g>\n" );
 925|
 926|//  ASSERT( nInk == GetInkCount() );
 927|}
 928|
 929|
 930| 
 931|/***********************************************************************
 932|  9. <<< [CChildView::InInkSVG] インクデータを読み込む >>> 
 933|【引数】
 934|  ・FILE*  f;  ファイルポインタをインクデータの始まりの位置(base64)にしたファイルアクセス
 935|【補足】
 936|・<![CDATA[ または ]]> だけの行は無視します。
 937|************************************************************************/
 938|void  CChildView::InInkSVG( FILE* f )
 939|{
 940|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
 941|  IInkDisp*  ink;
 942|  VARIANT  rawInkData;
 943|  HRESULT  hr;
 944|  WCHAR*  rawInkDataX;
 945|  #ifndef NDEBUG
 946|    int  nInk = GetInkCount();
 947|  #endif
 948|
 949|  rawInkDataX = InInkRawData( f );
 950|  Variant_initBSTR( &rawInkData, rawInkDataX );
 951|
 952|  // NewInkOverlay();  // OnNew で行っているため
 953|
 954|  hr = m_InkOverlay->get_Ink( &ink );
 955|  if ( hr != 0 )  error();
 956|
 957|  hr = ink->Load( rawInkData );
 958|  if ( hr != S_OK )
 959|    error();
 960|
 961|  hr = m_InkRectangle->SetRectangle( /*top*/ 0, /*left*/ 0,
 962|    /*bottom*/ app->m_file.m_Canvas.m_Height * m_Zoom / 100, /*right*/ app->m_file.m_Canvas.m_Width * m_Zoom / 100 );
 963|  if ( hr != 0 )  error();
 964|
 965|  m_InkOverlay->SetWindowInputRectangle( m_InkRectangle );
 966|  if ( hr != 0 )  error();
 967|
 968|  hr = ink->Release();  ink = NULL;
 969|  if ( hr > 5 )  error();
 970|  Variant_finish( &rawInkData );
 971|  free( rawInkDataX );
 972|
 973|  Invalidate( FALSE );  /* 再描画する */
 974|
 975|  ASSERT( nInk == GetInkCount() );
 976|}
 977|
 978|
 979| 
 980|/***********************************************************************
 981|  10. <<< [CChildView::InInkRawData] インクデータを読み込む >>> 
 982|【引数】
 983|  ・FILE*  f;  ファイルポインタをインクデータの始まりの位置(base64)にしたファイルアクセス
 984|  ・WCHAR*  返り値;  IInkDisp::Load に使えるインクデータ(要free)
 985|【補足】
 986|・<![CDATA[ または ]]> だけの行は無視します。
 987|************************************************************************/
 988|WCHAR*  CChildView::InInkRawData( FILE* f )
 989|{
 990|  int   i, iLine;
 991|  WCHAR*  rawInkDataX;
 992|  char  s[80];
 993|  WCHAR w[80];
 994|
 995|  rawInkDataX = (WCHAR*)malloc( 4 );
 996|
 997|  for ( iLine = 1; ; iLine++ ) {
 998|    fgets( s, sizeof(s), f );
 999|    if ( feof(f) ) { MessageBox("feof");  break; }
1000|    StrX_cutLastOf( s, '\n' );
1001|    StrX_cutLastOf( s, '\r' );
1002|
1003|    if ( strcmp( s, "</svgcats-ink-rawdata>" ) == 0 )  break;
1004|    if ( strcmp( s, "<![CDATA[" ) == 0 )  { iLine --;  continue; }
1005|    if ( strcmp( s, "]]>" ) == 0 )  { iLine --;  continue; }
1006|
1007|    for ( i = 0; i < 73; i++ ) {
1008|      if ( s[i] == '\0' )  break;
1009|      w[i] = (WCHAR)s[i];
1010|    }
1011|    w[i] = '\0';
1012|
1013|    if ( i > 0 ) {
1014|      rawInkDataX = (WCHAR*)realloc( rawInkDataX, iLine * 73*sizeof(WCHAR) + sizeof(WCHAR) );
1015|      memcpy( rawInkDataX + (iLine - 1) * 73,  w,  73*sizeof(WCHAR) );
1016|    }
1017|    else
1018|      iLine--;
1019|  }
1020|
1021|  return  rawInkDataX;
1022|}
1023| 
1024|/***********************************************************************
1025|  11. <<< [CChildView::IsDirty] 保存した状態と異なるかどうかを返す >>> 
1026|************************************************************************/
1027|bool  CChildView::IsDirty()
1028|{
1029|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
1030|  IInkDisp*  ink;
1031|  VARIANT_BOOL  bDirty;
1032|  HRESULT  hr;
1033|  #ifndef NDEBUG
1034|    int  nInk = GetInkCount();
1035|  #endif
1036|
1037|  if ( m_InkOverlay != NULL ) {
1038|
1039|    hr = m_InkOverlay->get_Ink( &ink );
1040|    if ( hr != 0 )  error();
1041|    hr = ink->get_Dirty( &bDirty );
1042|    if ( hr != 0 )  error();
1043|
1044|    hr = ink->Release();  ink = NULL;
1045|
1046|    // ASSERT( nInk == GetInkCount() );
1047|  }
1048|  else
1049|    bDirty = false;
1050|
1051|
1052|  return  ( app->m_UndoBuf->IsModify() || /* bDirty || */
1053|    ( m_BeforePrim != NULL && ! m_bDrag ) );
1054|}
1055|
1056|
1057|#ifndef  NDEBUG
1058|int  CChildView::GetInkCount()
1059|{
1060|  IInkDisp*  ink;
1061|  HRESULT  hr;
1062|
1063|  if ( m_InkOverlay == NULL )  return 0;
1064|
1065|  hr = m_InkOverlay->get_Ink( &ink );
1066|  if ( hr != 0 )  error();
1067|
1068|  return  ink->Release();  ink = NULL;
1069|}
1070|#endif
1071|
1072|
1073| 
1074|/***********************************************************************
1075|  12. <<< [CChildView::OnPaint] OSから描画を要求されたときの処理 >>> 
1076|************************************************************************/
1077|#include <wingdi.h>
1078|void CChildView::OnPaint()
1079|{
1080|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
1081|  CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
1082|  CPaintDC  dc( this );
1083|  CPoint  pt = GetScrollPosition();
1084|  int     w = app->m_file.m_Canvas.m_Width * m_Zoom / 100 - pt.x;
1085|  int     h = app->m_file.m_Canvas.m_Height * m_Zoom / 100 - pt.y;
1086|  CRect   rect;
1087|  #ifndef NDEBUG
1088|    int  nInk = GetInkCount();
1089|  #endif
1090|
1091|  ERRORS_FUNC_CPP_VAR( CChildView_OnPaint );
1092|
1093|  if ( Errors_bExiting )  return;
1094|  if ( m_bPrinting )  return;
1095|
1096|  ERRORS_FUNC_START_CPP( CChildView_OnPaint );
1097|
1098|  if ( frame->m_mode == CMainFrame_Zooming ) {
1099|
1100|    Zoom( m_ZoomNext );
1101|    DrawOutOfCanvas( &dc );
1102|
1103|    ERRORS_FUNC_END_CPP( CChildView_OnPaint );
1104|    return;
1105|  }
1106|
1107|  /* メモリバッファを生成する */
1108|  if ( ! m_bFirstPainted || ! m_bBitmap ) {
1109|    CDC*  dc;
1110|    CBitmap*  oldBitmap;
1111|    int  newWidth = app->m_file.m_Canvas.m_Width * m_Zoom / 100;
1112|    int  newHeight = app->m_file.m_Canvas.m_Height * m_Zoom / 100;
1113|    RECT  clientRect;
1114|
1115|    GetClientRect( &clientRect );
1116|    if ( newWidth > clientRect.right )  newWidth = clientRect.right;
1117|    if ( newHeight > clientRect.bottom )  newHeight = clientRect.bottom;
1118|
1119|    if ( newWidth > m_BitmapWidth || newHeight > m_BitmapHeight ) {
1120|      dc = GetDC();
1121|
1122| 
1123|      m_Bitmap = new CBitmap; 
1124|      if ( newWidth > m_BitmapWidth )   m_BitmapWidth = newWidth;
1125|      if ( newHeight > m_BitmapHeight ) m_BitmapHeight = newHeight;
1126|      m_Bitmap->CreateCompatibleBitmap( dc, m_BitmapWidth, m_BitmapHeight );
1127|      oldBitmap = m_BitmapDC.SelectObject( m_Bitmap );
1128|      if ( m_bFirstPainted && ! m_bBitmap ) {
1129|        delete  oldBitmap;
1130|      }
1131|
1132|      m_MinBitmap = new CBitmap;
1133|      m_MinBitmap->CreateCompatibleBitmap( dc, 64, 64 );
1134|      oldBitmap = m_MinBitmapDC.SelectObject( m_MinBitmap );
1135|      if ( m_bFirstPainted && ! m_bBitmap ) {
1136|        delete  oldBitmap;
1137|      }
1138|
1139|      #ifdef  SVGCAT_USES_BACKBUF
1140|      m_BackBitmap = new CBitmap;
1141|      m_BackBitmap->CreateCompatibleBitmap( dc, 64, 64 );
1142|      oldBitmap = m_BackBitmapDC.SelectObject( m_BackBitmap );
1143|      if ( m_bFirstPainted && ! m_bBitmap ) {
1144|        delete  oldBitmap;
1145|      }
1146|      #endif
1147|
1148|      ReleaseDC( dc );
1149|      m_bBitmap = TRUE;
1150|      SetScrollSize();
1151|    }
1152|  }
1153|
1154|  if ( ! m_bEnableOnPaint )  return;
1155|
1156|
1157|  GetClientRect( &rect );
1158|  if ( w > rect.right )  w = rect.right;
1159|  if ( h > rect.bottom )  h = rect.bottom;
1160|
1161|
1162|  /* 図形を描画する1 */
1163|  if ( m_backSurf != NULL ) {
1164|    HDC    hdc;
1165|    CDC*   dc2;
1166|    IDirectDrawClipper*  clip;
1167|    RECT  src, dst;
1168|    HRESULT  hr;
1169|
1170|    /* カラーキーの設定(何故か設定したほうが速い?) */
1171|    DDCOLORKEY ddck;
1172|    ddck.dwColorSpaceLowValue = 12; RGB(0xFF,0xFF,0xFF);
1173|    ddck.dwColorSpaceHighValue = 12; RGB(0xFF,0xFF,0xFF);
1174|    hr = m_backSurf->SetColorKey( DDCKEY_SRCBLT, &ddck );
1175|    if ( hr != DD_OK ) {
1176|      if ( hr == DDERR_CANTCREATEDC || hr == DDERR_SURFACELOST ) {
1177|        m_backSurf = NULL;
1178|        goto ElseInException;
1179|      }
1180|      Errors_printf_release("%X",hr);
1181|      error();
1182|    }
1183|
1184|    /* 図形を描画する */
1185|    hr = m_backSurf->GetDC( &hdc );
1186|    if ( hr != DD_OK ) {  /* 画面を横から縦に変えたときにエラーが発生 */
1187|      if ( hr == DDERR_CANTCREATEDC || hr == DDERR_SURFACELOST ) {
1188|        m_backSurf = NULL;
1189|        goto ElseInException;
1190|      }
1191|      Errors_printf_release("%X",hr);
1192|      error();
1193|    }
1194|    dc2 = CDC::FromHandle( hdc );
1195|    DrawAll( dc2, true );
1196|    dc2->Detach();
1197|    hr = m_backSurf->ReleaseDC( hdc );  if ( hr != DD_OK ) error();
1198|
1199|    src.left = m_MinusOffset.x;  src.top = m_MinusOffset.y;
1200|    src.right = src.left + w;  src.bottom = src.top + h;
1201|    GetClientRect( &dst );
1202|    ClientToScreen( &dst );
1203|    dst.right = dst.left + w;  dst.bottom = dst.top + h;
1204|
1205|    hr = m_ddraw->CreateClipper( 0, &clip, 0 );  if ( hr != DD_OK ) error();
1206|    hr = clip->SetHWnd( 0, m_hWnd );  if ( hr != DD_OK ) error();
1207|    hr = m_priSurf->SetClipper( clip );  if ( hr != DD_OK ) error();
1208|
1209|    if ( src.left < src.right && src.top < src.bottom ) {
1210|      hr = m_priSurf->Blt( &dst, m_backSurf, &src, DDBLT_KEYSRC, NULL );
1211|      if ( hr != DD_OK )
1212|        error();
1213|    }
1214|    clip->Release();
1215|  }
1216|ElseInException:
1217|
1218|  if ( m_backSurf == NULL ) {
1219|    DrawAll( &m_BitmapDC, true );
1220|    dc.SelectClipRgn( NULL );
1221|    dc.BitBlt( m_MinusOffset.x, m_MinusOffset.y, w, h,  &m_BitmapDC, 0,0, SRCCOPY );
1222|      /* この dc は、クライアント領域座標 */
1223|  }
1224|  DrawOutOfCanvas( &dc );
1225|
1226|  ERRORS_FUNC_END_CPP( CChildView_OnPaint );
1227|}
1228|
1229|
1230| 
1231|/***********************************************************************
1232|  13. <<< [CChildView::OnPrint] プリンタに印刷する >>> 
1233|************************************************************************/
1234|void CChildView::OnPrint()
1235|{
1236|  CSVGCatApp*   app = (CSVGCatApp*)AfxGetApp();
1237|  CPrintDialog  dlg( FALSE, NULL, this );
1238|  int  pageNum, iCopy, iCopy2, nCopy, nCopy2;
1239|
1240|  m_bPrinting = true;
1241|
1242|  dlg.m_pd.nMinPage = 1;
1243|  dlg.m_pd.nMaxPage = SVGCat_File_getMaxPageNum( &app->m_file );
1244|  dlg.m_pd.nFromPage = dlg.m_pd.nMinPage;
1245|  dlg.m_pd.nToPage = dlg.m_pd.nMaxPage;
1246|  dlg.m_pd.Flags &= ~( PD_ENABLEPRINTTEMPLATE );
1247|  dlg.m_pd.Flags |= PD_ALLPAGES | PD_NOSELECTION | PD_COLLATE | PD_USEDEVMODECOPIESANDCOLLATE;
1248|
1249|  if ( dlg.DoModal() == IDOK ) {
1250|    CDC  dc;
1251|    DOCINFO  info;
1252|    char  name[256];
1253|    int  zoom;
1254|    int  horizontal, vertical;
1255|    SVGCat_Page*  page;
1256|    SVGCat_Page*  backPage;
1257|    CMainFrame*   frame = (CMainFrame*)GetParent()->GetParent();
1258|
1259|    CWaitCursor  wa;
1260|
1261|    app->ChgPage( &app->m_file, app->m_file.m_CurrentPageNum );  /* 同期を取る */
1262|    if ( app->m_file.m_StartPageNum == 0 )
1263|      backPage = ListX_getFirst( &app->m_file.m_pages, SVGCat_Page );
1264|    else
1265|      backPage = NULL;
1266|
1267|    dc.Attach( dlg.GetPrinterDC() );
1268|
1269|    memset( &info, 0, sizeof(info) );
1270|    info.cbSize = sizeof(info);
1271|    info.lpszDocName = name;
1272|    StrX_cpyFName( name, app->m_path );
1273|
1274|    #if ERRORS_DEBUG_FALSE
1275|      Errors_printf( "Device %dx%d", dc.GetDeviceCaps( HORZRES ), dc.GetDeviceCaps( VERTRES ) );
1276|    #endif
1277|
1278|    zoom = m_Zoom;
1279|    horizontal = dc.GetDeviceCaps( HORZRES );
1280|    vertical = dc.GetDeviceCaps( VERTRES );
1281|    m_Zoom = horizontal * 1719 * 100 / (Canvas_A4_W * 2100);
1282|      // 日本の A4 サイズは、210mm x 297mm
1283|      // 19.05 + 19.05 + x = 210.0 , x = 171.9
1284|      // 水平ピクセル数 / Canvas_A4_W 倍、マージンを除いた 171.9/210.0倍
1285|
1286|    if ( dlg.m_pd.Flags & PD_COLLATE )
1287|      { nCopy = dlg.m_pd.nCopies;  nCopy2 = 1; }
1288|    else
1289|      { nCopy = 1;  nCopy2 = dlg.m_pd.nCopies; }  /* nCopy2は常に1、ドライバ側が複数印刷する? */
1290|
1291|    for ( iCopy = 1; iCopy <= nCopy; iCopy ++ ) {
1292|
1293|      dc.StartDoc( &info );
1294|
1295|      for ( ListX_forEach( &app->m_file.m_pages, &page, SVGCat_Page ) ) {
1296|        if ( page == backPage )  continue;
1297|
1298|        pageNum = SVGCat_File_getPageNum( &app->m_file, page );
1299|        if ( pageNum < dlg.m_pd.nFromPage || pageNum > dlg.m_pd.nToPage )
1300|          continue;
1301|
1302|        { char  s[256];
1303|          sprintf( s, "印刷中 (%d/%d) ...", pageNum - dlg.m_pd.nFromPage + 1,
1304|            dlg.m_pd.nToPage - dlg.m_pd.nFromPage + 1 );
1305|          frame->SetWindowText( s );
1306|        }
1307|
1308|        for ( iCopy2 = 1; iCopy2 <= nCopy2; iCopy2 ++ ) {
1309|          dc.StartPage();
1310|          if ( backPage != NULL )  PrintSub( &dc, backPage, pageNum, zoom, horizontal, vertical );
1311|          PrintSub( &dc, page, pageNum, zoom, horizontal, vertical );
1312|          dc.EndPage();
1313|        }
1314|      }
1315|      dc.EndDoc();
1316|    }
1317|    m_Zoom = zoom;
1318|
1319|    DeleteDC( dc.Detach() );
1320|    frame->UpdateWindowText();
1321|  }
1322|
1323|  m_bPrinting = false;
1324|}
1325|
1326|
1327|
1328|void CChildView::PrintSub( CDC* dc, SVGCat_Page* page, int pageNum, int zoom_ras,
1329|  int horizontal, int vertical )
1330|{
1331|  CSVGCatApp*   app = (CSVGCatApp*)AfxGetApp();
1332|  CadPrim_DrawParam  p;
1333|  ListX_ElemX*  pPrim;
1334|
1335|  /* 全部の図形を描画する */
1336|  GetDrawParam( &p );
1337|  p.bPrint = true;
1338|  p.x0 = p.y0 = - horizontal * 19 / 210;
1339|  p.clip_left += horizontal * 19 / 210;
1340|  p.clip_right += horizontal * 19 / 210;
1341|  p.clip_top += vertical * 19 / 297;
1342|  p.clip_bottom += vertical * 19 / 297;
1343|  p.bWhiteToBGColor = false;
1344|  p.bDrawHandle = false;
1345|  p.iPage = pageNum;
1346|  for ( ListX_forEach( &page->prims, &pPrim, ListX_ElemX ) ) {
1347|    ((CadPrim*)pPrim->p)->Draw( dc, &p );
1348|  }
1349|
1350|
1351|  /* インクを印刷する */
1352|  if ( m_InkOverlay != NULL ) {
1353|    HRESULT  hr;
1354|    IInkRenderer*  render;
1355|    IInkDisp* ink;
1356|    IInkStrokes*  strokes;
1357|    long  x, y;
1358|
1359|    m_InkOverlay->get_Renderer( &render );
1360|
1361|    hr = render->Move( m_prevX0, m_prevY0 );
1362|    if ( hr != 0 ) error();
1363|    hr = render->ScaleTransform( (float)100 / zoom_ras, (float)100 / zoom_ras );
1364|    if ( hr != 0 ) error();
1365|
1366|    hr = CoCreateInstance( CLSID_InkDisp, NULL, CLSCTX_INPROC_SERVER,
1367|                     IID_IInkDisp, (void**)&ink );
1368|    if ( hr != 0 )  error();
1369|    hr = ink->Load( page->ink );
1370|    if ( hr != S_OK )  error();
1371|
1372|    hr = ink->get_Strokes( &strokes );
1373|    if ( hr != 0 ) error();
1374|
1375|    x = horizontal * 19 / 210;
1376|    y = x;
1377|    render->PixelToInkSpace( (long)dc->m_hDC, &x, &y );
1378|    render->Move( (float)x, (float)y );
1379|    hr = render->Draw( (long)dc->m_hDC, strokes );
1380|    if ( hr != 0 ) error();
1381|    render->Move( (float)-x, (float)-y );
1382|
1383|    hr = render->ScaleTransform( (float)zoom_ras / 100, (float)zoom_ras / 100 );
1384|    if ( hr != 0 ) error();
1385|    hr = render->Move( -m_prevX0, -m_prevY0 );
1386|    if ( hr != 0 ) error();
1387|
1388|    hr = render->Release();  render = NULL;
1389|    if ( hr > 5 )  error();
1390|    hr = strokes->Release();  strokes = NULL;
1391|    if ( hr > 5 )  error();
1392|    hr = ink->Release();  ink = NULL;
1393|    if ( hr > 5 )  error();
1394|  }
1395|}
1396|
1397|
1398| 
1399|/***********************************************************************
1400|  14. <<< [CChildView::PaintToImage] ページを画像で出力する >>> 
1401|************************************************************************/
1402|extern "C" { bool  CompressToJpeg( int w, int h, int w_stride, char* bmp, int bReverse, int bpp, const char* out_path ); }
1403|
1404|
1405|void  CChildView::PaintToImage( int iPage, const char* path )
1406|{
1407|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
1408|  CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
1409|  int  w, h, w_max, h_max, w_stride;
1410|  int  zoom_ras;
1411|  CClientDC  dc(this);
1412|  CBitmap*  bitmap;
1413|  CDC  bitmapDC;
1414|  CBitmap*  oldBitmap;
1415|  BITMAP  bitmapInfo;
1416|  char*   buf;
1417|  HWND desktop = ::GetDesktopWindow();
1418|  HDC  desktopDC = ::GetDC( desktop );
1419|  int  bpp = GetDeviceCaps( desktopDC, BITSPIXEL );
1420|  SVGCat_Page*  page;
1421|  SVGCat_Page*  frontPage;
1422|  SVGCat_Page*  backPage;
1423|  CadPrim_DrawParam  p;
1424|  ListX_ElemX*  pPrim;
1425|  CWaitCursor  wa;
1426|
1427|  ERRORS_FUNC_CPP_VAR( CChildView_Redraw );
1428|  ERRORS_FUNC_START_CPP( CChildView_Redraw );
1429|
1430|  m_bPrinting = true;
1431|  zoom_ras = m_Zoom;  m_Zoom = 100;
1432|
1433|  app->ChgPage( &app->m_file, app->m_file.m_CurrentPageNum );  /* 同期を取る */
1434|  if ( app->m_file.m_StartPageNum == 0 )
1435|    backPage = ListX_getFirst( &app->m_file.m_pages, SVGCat_Page );
1436|  else
1437|    backPage = NULL;
1438|
1439|  #if 0
1440|  w_max = 0;  h_max = 0;
1441|  for ( ListX_forEach( &app->m_file.m_pages, &page, SVGCat_Page ) ) {
1442|    if ( page == backPage )  continue;
1443|    w = page->canvas.m_Width;
1444|    h = page->canvas.m_Height;
1445|    if ( w > w_max )  w_max = w;
1446|    if ( h > h_max )  h_max = h;
1447|  }
1448|  #else
1449|  frontPage = ListX_get( &app->m_file.m_pages, iPage - app->m_file.m_StartPageNum, SVGCat_Page );
1450|  w_max = frontPage->canvas.m_Width;
1451|  h_max = frontPage->canvas.m_Height;
1452|  #endif
1453|
1454|
1455|  bitmap = new CBitmap;
1456|  bitmap->CreateCompatibleBitmap( &dc, w_max, h_max );
1457|  bitmapDC.CreateCompatibleDC( &dc );
1458|  oldBitmap = bitmapDC.SelectObject( bitmap );
1459|
1460|  //w_stride = w_max * ( (bpp + 7) / 8 );  w_stride = (w_stride + 3) & ~3;
1461|  bitmap->GetBitmap( &bitmapInfo );
1462|  w_stride = bitmapInfo.bmWidthBytes;
1463|  buf = (char*)malloc( w_stride * h_max );
1464|
1465|
1466|  w = frontPage->canvas.m_Width;
1467|  h = frontPage->canvas.m_Height;
1468|
1469|
1470|  /* キャンパスをクリアする */
1471|  {
1472|    CPen    pen( PS_SOLID, 1, RGB(0xFF,0xFF,0xFF) );
1473|    CBrush  brush( RGB(0xFF,0xFF,0xFF) );
1474|    CPen*   oldPen = bitmapDC.SelectObject( &pen );
1475|    CBrush* oldBrush = bitmapDC.SelectObject( &brush );
1476|
1477|    bitmapDC.Rectangle( 0, 0, w, h );
1478|
1479|    bitmapDC.SelectObject( oldPen );
1480|    bitmapDC.SelectObject( oldBrush );
1481|  }
1482|
1483|
1484|  for ( page = backPage; ; page = frontPage ) {
1485|    if ( page == NULL )  continue;
1486|
1487|
1488|    /* 全部の図形を描画する */
1489|    GetDrawParam( &p );
1490|    p.x0 = 0;  p.y0 = 0;
1491|    p.bPrint = true;
1492|    p.clip_right = w;
1493|    p.clip_bottom = h;
1494|    p.bWhiteToBGColor = false;
1495|    p.bDrawHandle = false;
1496|    p.iPage = iPage;
1497|
1498|    for ( ListX_forEach( &page->prims, &pPrim, ListX_ElemX ) ) {
1499|      ((CadPrim*)pPrim->p)->Draw( &bitmapDC, &p );
1500|    }
1501|
1502|
1503|    /* インクを印刷する */
1504|    if ( m_InkOverlay != NULL ) {
1505|      HRESULT  hr;
1506|      IInkRenderer*  render;
1507|      IInkDisp* ink;
1508|      IInkStrokes*  strokes;
1509|
1510|      m_InkOverlay->get_Renderer( &render );
1511|
1512|      hr = render->Move( m_prevX0, m_prevY0 );
1513|      if ( hr != 0 ) error();
1514|      hr = render->ScaleTransform( (float)100 / zoom_ras, (float)100 / zoom_ras );
1515|      if ( hr != 0 ) error();
1516|
1517|      hr = CoCreateInstance( CLSID_InkDisp, NULL, CLSCTX_INPROC_SERVER,
1518|                     IID_IInkDisp, (void**)&ink );
1519|      if ( hr != 0 )  error();
1520|      hr = ink->Load( page->ink );
1521|      if ( hr != S_OK )  error();
1522|
1523|      hr = ink->get_Strokes( &strokes );
1524|      if ( hr != 0 ) error();
1525|
1526|      hr = render->Draw( (long)bitmapDC.m_hDC, strokes );
1527|      if ( hr != 0 ) error();
1528|
1529|      hr = render->ScaleTransform( (float)zoom_ras / 100, (float)zoom_ras / 100 );
1530|      if ( hr != 0 ) error();
1531|      hr = render->Move( -m_prevX0, -m_prevY0 );
1532|      if ( hr != 0 ) error();
1533|
1534|      hr = render->Release();  render = NULL;
1535|      if ( hr > 5 )  error();
1536|      hr = strokes->Release();  strokes = NULL;
1537|      if ( hr > 5 )  error();
1538|      hr = ink->Release();  ink = NULL;
1539|      if ( hr > 5 )  error();
1540|    }
1541|
1542|    if ( page == frontPage )  break;
1543|  }
1544|
1545|  bitmap->GetBitmapBits( w_stride * h, buf );
1546|  if ( stricmp( StrX_refExt( path ), "png" ) == 0 )
1547|    frame->CompressToPng( w, h, w_stride, buf, bpp, path );
1548|  else {
1549|    if ( ! CompressToJpeg( w, h, w_stride, buf, false, bpp, path ) ) {
1550|      free( buf );
1551|      delete  bitmap;
1552|      error2_1( FileX_Err_CannotWrite, "%s を開けません。", path );
1553|    }
1554|  }
1555|
1556|  free( buf );
1557|  bitmapDC.SelectObject( oldBitmap );
1558|  bitmapDC.DeleteDC();
1559|  delete  bitmap;
1560|
1561|  m_Zoom = zoom_ras;
1562|  m_bPrinting = false;
1563|
1564|  ERRORS_FUNC_END_CPP( CChildView_Redraw );
1565|}
1566|
1567|
1568|
1569| 
1570|void  CChildView::OnDraw( CDC* pDC ) 
1571|{
1572|  ERRORS_FUNC_CPP_VAR( CChildView_OnDraw );
1573|  ERRORS_FUNC_START_CPP( CChildView_OnDraw );
1574|
1575|  Redraw( true );
1576|
1577|  ERRORS_FUNC_END_CPP( CChildView_OnDraw );
1578|}
1579|
1580|
1581| 
1582|/***********************************************************************
1583|  15. <<< [CChildView::Redraw] 再描画する >>> 
1584|************************************************************************/
1585|void CChildView::Redraw( bool bAll )
1586|{
1587|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
1588|  CPoint pt = GetScrollPosition();
1589|  int  w = app->m_file.m_Canvas.m_Width * m_Zoom / 100 - pt.x;
1590|  int  h = app->m_file.m_Canvas.m_Height * m_Zoom / 100 - pt.y;
1591|  RECT  rect;
1592|
1593|  ERRORS_FUNC_CPP_VAR( CChildView_Redraw );
1594|  ERRORS_FUNC_START_CPP( CChildView_Redraw );
1595|
1596|  if ( m_bExistOutOfCanvas )  bAll = true;
1597|
1598|  if ( m_hWnd == NULL ) {
1599|    ERRORS_FUNC_END_CPP( CChildView_Redraw );
1600|    return;
1601|  }
1602|
1603|  CClientDC  dc( this );
1604|
1605|  DrawAll( &m_BitmapDC, true );
1606|
1607|  GetClientRect( &rect );
1608|  if ( w > rect.right )  w = rect.right;
1609|  if ( h > rect.bottom )  h = rect.bottom;
1610|
1611|  dc.BitBlt( m_MinusOffset.x, m_MinusOffset.y,
1612|    w, h, &m_BitmapDC, 0, 0, SRCCOPY );
1613|
1614|  if ( bAll )
1615|    DrawOutOfCanvas( &dc );
1616|
1617|  ERRORS_FUNC_END_CPP( CChildView_Redraw );
1618|}
1619|
1620|
1621| 
1622|/***********************************************************************
1623|  16. <<< [CChildView::DrawAll] すべての図形を描画する >>> 
1624|【引数】
1625|  ・CDC*  dc;      デバイス・コンテキスト
1626|************************************************************************/
1627|void  CChildView::DrawAll( CDC* dc, bool bClip, bool bScroll, bool bDisableDrawingHandle,
1628|  bool bDisableGrid )
1629|{
1630|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
1631|  CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
1632|  const  POINT  pt0 = {0,0};
1633|  CPoint  pt = ( bScroll ? GetScrollPosition() : pt0 );
1634|  ListX_ElemX*  pPrim;
1635|  RECT  rc;
1636|  CRgn  clip;
1637|  CadPrim_DrawParam  p;
1638|  #ifndef NDEBUG
1639|    int  nInk = GetInkCount();
1640|  #endif
1641|
1642|  ERRORS_FUNC_CPP_VAR( CChildView_DrawAll );
1643|  ERRORS_FUNC_START_CPP( CChildView_DrawAll );
1644|
1645|  if ( dc->m_hDC == NULL ) {
1646|    ERRORS_FUNC_END_CPP( CChildView_DrawAll );
1647|    return;
1648|  }
1649|
1650|  GetDrawParam( &p );
1651|  p.iPage = app->m_file.m_CurrentPageNum;
1652|
1653|
1654|  /* クリアする */
1655|  p.bWhiteToBGColor = (app->m_bBackTransparent != 0);
1656|  if ( ! bScroll )  { p.x0 = pt.x;  p.y0 = pt.y; }
1657|  app->m_file.m_Canvas.Draw( dc, &p );
1658|
1659|
1660|  /* クリッピングする(拡大時の高速化) */
1661|  if ( m_bExistOutOfCanvas ) {
1662|    dc->SelectClipRgn( NULL );
1663|  }
1664|  else {
1665|    if ( bClip ) {
1666|      int  n;
1667|
1668|      GetClientRect( &rc );
1669|      n = app->m_file.m_Canvas.m_Width * m_Zoom / 100;
1670|      if ( n < rc.right )  rc.right = n;
1671|      n = app->m_file.m_Canvas.m_Height * m_Zoom / 100;
1672|      if ( n < rc.bottom )  rc.bottom = n;
1673|      clip.CreateRectRgn( 0,  0,  rc.right,  rc.bottom );
1674|      dc->SelectClipRgn( &clip );
1675|    }
1676|    else {
1677|      dc->SelectClipRgn( NULL );
1678|    }
1679|  }
1680|
1681|
1682|  /* 背景を描画する */
1683| #ifdef  SVGCAT_USES_BACKBUF
1684|  if ( m_bBackBitmap && app->m_file.m_CurrentPageNum != 0 && app->m_file.m_StartPageNum == 0 ) {
1685|    int     w, h;
1686|    SVGCat_Page*  backPage = ListX_getFirst( &app->m_file.m_pages, SVGCat_Page );
1687|
1688|    GetClientRect( &rc );
1689|    w = backPage->canvas.m_Width * p.zoom / 100;
1690|    h = backPage->canvas.m_Height * p.zoom / 100;
1691|    if ( w > rc.right )  w = rc.right;
1692|    if ( h > rc.bottom )  h = rc.bottom;
1693|
1694|    if ( pt.x != m_BackBitmapOffset.x || pt.y != m_BackBitmapOffset.y ||
1695|         w > m_BackBitmapWidth || h > m_BackBitmapHeight )
1696|      DrawBackBitmap();
1697|
1698|   #if 0
1699|    #if 1
1700|      WinX_DDBmp_readDirect( &m_BackBmp, dc->m_hDC, m_MinusOffset.x, m_MinusOffset.y );  /* DC性能: 11ms/1MB, DirectDraw性能: 10ms/1MB */
1701|    #else
1702|      bmpDC = WinX_DDBmp_openForRead( &m_BackBmp, dc->m_hDC );  /* 性能: 30.0ms/1MB */
1703|      BitBlt( dc->m_hDC, m_MinusOffset.x, m_MinusOffset.y,
1704|        m_BackBmp.width, m_BackBmp.height, bmpDC, 0, 0, SRCCOPY );  /* 性能: 1.9ms/SVGA */
1705|      WinX_DDBmp_closeForRead( &m_BackBmp );
1706|    #endif
1707|   #else
1708|      BitBlt( dc->m_hDC, m_MinusOffset.x, m_MinusOffset.y,
1709|        m_BackBmp.width, m_BackBmp.height, m_BackBitmapDC.m_hDC, 0, 0, SRCCOPY );  /* 性能: 1.9ms/SVGA */
1710|   #endif
1711|  }
1712| #else
1713|  /* 背景図形を描画する */
1714|  if ( app->m_file.m_CurrentPageNum != 0 && app->m_file.m_StartPageNum == 0 ) {
1715|    SVGCat_Page*  page = ListX_getFirst( &app->m_file.m_pages, SVGCat_Page );
1716|
1717|    if ( ! bScroll )  { p.x0 = pt.x;  p.y0 = pt.y; }
1718|    for ( ListX_forEach( &page->prims, &pPrim, ListX_ElemX ) ) {
1719|      ((CadPrim*)pPrim->p)->Draw( dc, &p );
1720|    }
1721|
1722|    #if  defined(InkRedraw)
1723|    /* インクを描画する */
1724|    if ( m_InkOverlay != NULL ) {
1725|      HRESULT  hr;
1726|      IInkRenderer* render;
1727|      IInkDisp*     ink;
1728|      IInkStrokes*  strokes;
1729|      long  x, y;
1730|      float xf, yf;
1731|
1732|      hr = m_InkOverlay->get_Renderer( &render );
1733|      if ( hr != 0 ) error();
1734|
1735|
1736|      /* 座標系を変換する */
1737|      if ( pt != m_prevScrollPos || m_Zoom != m_prevZoom ) {
1738|             /* 座標系をかえると図形とインクの再描画の無限ループになってしまう */
1739|
1740|        if ( m_prevX0 != 0 || m_prevY0 != 0 ) {
1741|          hr = render->Move( m_prevX0, m_prevY0 );  /* PixelToInkSpace の基準座標を戻す */
1742|          if ( hr != 0 ) error();
1743|        }
1744|
1745|        if ( m_Zoom != m_prevZoom ) {
1746|          hr = render->ScaleTransform( (float)m_Zoom / m_prevZoom, (float)m_Zoom / m_prevZoom );
1747|          if ( hr != 0 ) error();
1748|          m_prevZoom = m_Zoom;
1749|        }
1750|
1751|        x = pt.x;  y = pt.y;
1752|        hr = render->PixelToInkSpace( (long)dc->m_hDC, &x, &y );  if ( hr != 0 ) error();
1753|        xf = (float)x * m_Zoom / 100;  yf = (float)y * m_Zoom / 100;
1754|        m_prevScrollPos = pt;
1755|
1756|        m_prevX0 = xf;  m_prevY0 = yf;
1757|        if ( m_prevX0 != 0 || m_prevY0 != 0 ) {
1758|          hr = render->Move( -m_prevX0, -m_prevY0 );
1759|          if ( hr != 0 ) error();
1760|        }
1761|      }
1762|
1763|
1764|      /* 全インクを描画する */
1765|      hr = CoCreateInstance( CLSID_InkDisp, NULL, CLSCTX_INPROC_SERVER,
1766|                       IID_IInkDisp, (void**)&ink );
1767|      if ( hr != 0 )  error();
1768|      ink->Load( page->ink );
1769|
1770|      hr = ink->get_Strokes( &strokes ); if ( hr != 0 ) error();
1771|      hr = render->Draw( (long)dc->m_hDC, strokes );  if ( hr != 0 ) error();
1772|
1773|
1774|      strokes->Release();  strokes = NULL;
1775|      ink->Release();  ink = NULL;
1776|      render->Release();  render = NULL;
1777|    }
1778|    #endif
1779|  }
1780| #endif
1781|
1782|
1783|  /* 全部の図形を描画する */
1784|  if ( ! bScroll )  { p.x0 = pt.x;  p.y0 = pt.y; }
1785|  for ( ListX_forEach( &app->m_file.m_prims, &pPrim, ListX_ElemX ) ) {
1786|    ((CadPrim*)pPrim->p)->Draw( dc, &p );
1787|  }
1788|
1789|
1790|  #if  defined(InkRedraw)
1791|  /* インクを描画する */
1792|  if ( m_InkOverlay != NULL ) {
1793|    HRESULT  hr;
1794|    IInkRenderer* render;
1795|    IInkDisp*     ink;
1796|    IInkStrokes*  strokes;
1797|    long  x, y;
1798|    float xf, yf;
1799|
1800|    hr = m_InkOverlay->get_Renderer( &render );
1801|    if ( hr != 0 ) error();
1802|
1803|
1804|    /* 座標系を変換する */
1805|    if ( pt != m_prevScrollPos || m_Zoom != m_prevZoom ) {
1806|           /* 座標系をかえると図形とインクの再描画の無限ループになってしまう */
1807|
1808|      if ( m_prevX0 != 0 || m_prevY0 != 0 ) {
1809|        hr = render->Move( m_prevX0, m_prevY0 );  /* PixelToInkSpace の基準座標を戻す */
1810|        if ( hr != 0 ) error();
1811|      }
1812|
1813|      if ( m_Zoom != m_prevZoom ) {
1814|        hr = render->ScaleTransform( (float)m_Zoom / m_prevZoom, (float)m_Zoom / m_prevZoom );
1815|        if ( hr != 0 ) error();
1816|        m_prevZoom = m_Zoom;
1817|      }
1818|
1819|      x = pt.x;  y = pt.y;
1820|      hr = render->PixelToInkSpace( (long)dc->m_hDC, &x, &y );  if ( hr != 0 ) error();
1821|      xf = (float)x * m_Zoom / 100;  yf = (float)y * m_Zoom / 100;
1822|      m_prevScrollPos = pt;
1823|
1824|      m_prevX0 = xf;  m_prevY0 = yf;
1825|      if ( m_prevX0 != 0 || m_prevY0 != 0 ) {
1826|        hr = render->Move( -m_prevX0, -m_prevY0 );
1827|        if ( hr != 0 ) error();
1828|      }
1829|    }
1830|    hr = m_InkOverlay->get_Ink( &ink );  if ( hr != 0 ) error();
1831|
1832|
1833|    /* 全インクを描画する */
1834|    hr = ink->get_Strokes( &strokes ); if ( hr != 0 ) error();
1835|    hr = render->Draw( (long)dc->m_hDC, strokes );  if ( hr != 0 ) error();
1836|
1837|
1838|    /* 選択状態のインクを表示する */
1839|    if ( m_HoldStrokes != NULL && ! m_bDrag ) {
1840|      IInkDrawingAttributes*  attr;
1841|      IInkDrawingAttributes**  attr_orgs;
1842|      IInkStrokeDisp*  stroke;
1843|      long  iStroke, nStroke;
1844|      float x;
1845|      InkRasterOperation*  rasters;
1846|      long*  colors;
1847|      COLORREF  canvasColor;
1848|
1849|      /* 右ドラッグのとき、余計なストロークが入ることがたまにあるのでそれをカットする */
1850|      {
1851|        long  i, n, id, id2;
1852|        IInkStrokeDisp*  stroke2;
1853|
1854|        hr = m_HoldStrokes->get_Count( &nStroke );  if ( hr != 0 ) error();
1855|        for ( iStroke = 0; iStroke < nStroke; iStroke ++ ) {
1856|          hr = m_HoldStrokes->Item( iStroke, &stroke );  if ( hr != 0 ) error();
1857|          hr = strokes->get_Count( &n );
1858|          hr = stroke->get_ID( &id );
1859|          for ( i = 0; i < n; i++ ) {
1860|            hr = strokes->Item( i, &stroke2 );  if ( hr != 0 ) error();
1861|            hr = stroke2->get_ID( &id2 );  if ( hr != 0 ) error();
1862|            hr = stroke2->Release();  stroke2 = NULL;  if ( hr != 0 ) error();
1863|            if ( id == id2 )  break;
1864|          }
1865|          if ( i == n ) {
1866|            hr = m_HoldStrokes->Remove( stroke );  if ( hr != 0 ) error();
1867|            iStroke --;  nStroke--;
1868|          }
1869|          hr = stroke->Release();  stroke = NULL;
1870|        }
1871|      }
1872|
1873|      /* 選択状態のインクを描画する */
1874|      hr = m_HoldStrokes->get_Count( &nStroke );  if ( hr != 0 ) error();
1875|      attr_orgs = (IInkDrawingAttributes**)malloc( sizeof(int*) * nStroke );
1876|      rasters = (InkRasterOperation*)malloc( sizeof(int) * nStroke );
1877|      colors = (long*)malloc( sizeof(long) * nStroke );
1878|
1879|      canvasColor = ( app->m_bBackTransparent ?
1880|        GetSysColor( COLOR_WINDOW ) : RGB( 0xFF, 0xFF, 0xFF ) );
1881|
1882|      for ( iStroke = 0; iStroke < nStroke; iStroke ++ ) {
1883|        hr = m_HoldStrokes->Item( iStroke, &stroke );  if ( hr != 0 ) error();
1884|
1885|        hr = stroke->get_DrawingAttributes( &attr_orgs[iStroke] );
1886|        if ( hr != 0 ) {  /* ディレイされた削除が原因? */
1887|          hr = m_HoldStrokes->Remove( stroke );
1888|          if ( hr != 0 )  error();
1889|          iStroke--;  nStroke--;
1890|          stroke->Release();  stroke = NULL;
1891|          continue;
1892|        }
1893|        attr = attr_orgs[iStroke];
1894|        hr = attr->get_Width( &x );  if ( hr != 0 ) error();
1895|        hr = attr->put_Width( x + 40 );  if ( hr != 0 ) error();
1896|        hr = attr->get_Height( &x );  if ( hr != 0 ) error();
1897|        hr = attr->put_Height( x + 40 );  if ( hr != 0 ) error();
1898|        hr = attr->get_RasterOperation( &rasters[iStroke] );  if ( hr != 0 ) error();
1899|        hr = attr->put_RasterOperation( IRO_CopyPen );  if ( hr != 0 ) error();
1900|        hr = stroke->putref_DrawingAttributes( attr );  if ( hr != 0 ) error();
1901|        hr = stroke->Release();  stroke = NULL;
1902|      }
1903|      hr = render->Draw( (long)dc->m_hDC, m_HoldStrokes );  if ( hr != 0 ) error();
1904|
1905|      for ( iStroke = 0; iStroke < nStroke; iStroke ++ ) {
1906|        hr = m_HoldStrokes->Item( iStroke, &stroke );  if ( hr != 0 ) error();
1907|        attr = attr_orgs[iStroke];
1908|        hr = attr->get_Width( &x );  if ( hr != 0 ) error();
1909|        hr = attr->put_Width( x - 40 );  if ( hr != 0 ) error();
1910|        hr = attr->get_Height( &x );  if ( hr != 0 ) error();
1911|        hr = attr->put_Height( x - 40 );  if ( hr != 0 ) error();
1912|        hr = attr->get_Color( &colors[iStroke] );  if ( hr != 0 ) error();
1913|        hr = attr->put_Color( canvasColor );  if ( hr != 0 ) error();
1914|        hr = stroke->putref_DrawingAttributes( attr );  if ( hr != 0 ) error();
1915|        hr = stroke->Release();  stroke = NULL;
1916|      }
1917|      hr = render->Draw( (long)dc->m_hDC, m_HoldStrokes );  if ( hr != 0 ) error();
1918|
1919|      for ( iStroke = 0; iStroke < nStroke; iStroke ++ ) {
1920|        hr = m_HoldStrokes->Item( iStroke, &stroke );  if ( hr != 0 ) error();
1921|        attr = attr_orgs[iStroke];
1922|        hr = attr->put_Color( colors[iStroke] );  if ( hr != 0 ) error();
1923|        hr = attr->put_RasterOperation( rasters[iStroke] );  if ( hr != 0 ) error();
1924|        hr = stroke->putref_DrawingAttributes( attr );  if ( hr != 0 ) error();
1925|        hr = attr->Release();  attr = NULL;
1926|        hr = stroke->Release();  stroke = NULL;
1927|      }
1928|
1929|      /* インクをリサイズをするためのハンドルを描画する */
1930|      if ( nStroke > 0 ) {
1931|        COLORREF  color = GetSysColor( COLOR_HIGHLIGHT );
1932|        CPen     pen( PS_SOLID, 1, color ^ 0xFFFFFF );
1933|        CBrush   brush( color );
1934|        CPen*    oldPen;
1935|        CBrush*  oldBrush;
1936|        int  x = m_InkResizeHandlePos.x * m_Zoom / 100 - pt.x;
1937|        int  y = m_InkResizeHandlePos.y * m_Zoom / 100 - pt.y;
1938|
1939|        oldPen = dc->SelectObject( &pen );
1940|        oldBrush = dc->SelectObject( &brush );
1941|
1942|        dc->Rectangle( x - 3, y - 3, x + 3, y + 3 );
1943|
1944|        dc->SelectObject( oldBrush );
1945|        dc->SelectObject( oldPen );
1946|      }
1947|
1948|      free( colors );
1949|      free( attr_orgs );
1950|      free( rasters );
1951|    }
1952|
1953|    strokes->Release();  strokes = NULL;
1954|    ink->Release();  ink = NULL;
1955|    render->Release();  render = NULL;
1956|  }
1957|  #endif
1958|//ASSERT( nInk == GetInkCount() );
1959|
1960|  #ifndef  NDEBUG
1961|  if ( m_InkOverlay != NULL ) {
1962|    VARIANT_BOOL  b;
1963|    HRESULT  hr;
1964|
1965|    hr = m_InkOverlay->get_AutoRedraw( &b );
1966|    if ( hr != 0 )  error();
1967|    ASSERT( !b );
1968|  }
1969|  #endif
1970|
1971|
1972|  /* ハンドルを描画する */
1973|  /* メインに選択しているもの以外は、図形を描画したときに描画済みです。 */
1974|  if ( m_HoldPrim != NULL && p.bDrawHandle && ! bDisableDrawingHandle && ! m_bEditorEnable )
1975|    m_HoldPrim->DrawHandles( dc, &p, GetSysColor( COLOR_HIGHLIGHT ), true );
1976|
1977|  if ( ! bDisableGrid )  app->m_file.m_Canvas.DrawGrid( dc, &p );
1978|
1979|
1980|  if ( m_PrevCanvasHeight != -1 ) {
1981|    CPen  whiteDashPen( PS_DASHDOT, 1, RGB(0xFF,0xFF,0xFF) );
1982|    CPen  blackDashPen( PS_DASHDOT, 1, RGB(0,0,0) );
1983|    CPen*  oldPen;
1984|    CPoint  down;
1985|    int   y = m_DownY;
1986|    int   w = app->m_file.m_Canvas.m_Width;
1987|
1988|    down = m_DownS;
1989|
1990|
1991|    /* 行を挿入する範囲を描画する */
1992|    if ( y >= down.y || m_PrevCanvasHeight < -1 ) {
1993|      y = y * m_Zoom / 100 - p.y0;
1994|      w = w * m_Zoom / 100;
1995|      down.y = down.y * m_Zoom / 100 - p.y0;
1996|
1997|      dc->SetBkMode( TRANSPARENT );
1998|      oldPen = dc->SelectObject( &whiteDashPen );
1999|      dc->MoveTo( 0, down.y );
2000|      dc->LineTo( w, down.y );
2001|      dc->MoveTo( 0, y );
2002|      dc->LineTo( w, y );
2003|      oldPen = dc->SelectObject( &blackDashPen );
2004|      dc->MoveTo( 0, down.y + 1 );
2005|      dc->LineTo( w, down.y + 1 );
2006|      dc->MoveTo( 0, y + 1 );
2007|      dc->LineTo( w, y + 1 );
2008|      dc->SelectObject( oldPen );
2009|    }
2010|
2011|    /* 行を削除する範囲を描画する */
2012|    else {
2013|      RedrawWidthArea( dc, 0, y, w, down.y );
2014|    }
2015|  }
2016|
2017|
2018|  /* エディタを描画する */
2019|  if ( m_bEditorEnable )  m_Editor->Draw( dc, &p );
2020|
2021|
2022|  dc->SelectClipRgn( NULL );
2023|
2024|  Sleep(16);  /* 1/60秒。これが無いと、ドラッグ時に慣性が働くときがある */
2025|
2026|  ERRORS_FUNC_END_CPP( CChildView_DrawAll );
2027|}
2028|
2029|
2030| 
2031|/***********************************************************************
2032|  17. <<< [CChildView::ResetScrollAndScale] 拡大率やスクロール位置をリセットする >>> 
2033|************************************************************************/
2034|void  CChildView::ResetScrollAndScale()
2035|{
2036|  HRESULT  hr;
2037|  IInkRenderer* render;
2038|  POINT  pt = { 0, 0 };
2039|
2040|  ScrollToPosition( pt );
2041|
2042|  if ( m_InkOverlay != NULL ) {
2043|
2044|    hr = m_InkOverlay->get_Renderer( &render );
2045|    if ( hr != 0 ) error();
2046|
2047|    if ( m_prevX0 != 0 || m_prevY0 != 0 ) {
2048|      hr = render->Move( m_prevX0, m_prevY0 );  /* PixelToInkSpace の基準座標を戻す */
2049|      if ( hr != 0 ) error();
2050|    }
2051|
2052|    m_Zoom = 100;
2053|    if ( m_Zoom != m_prevZoom ) {
2054|      hr = render->ScaleTransform( (float)m_Zoom / m_prevZoom, (float)m_Zoom / m_prevZoom );
2055|      if ( hr != 0 ) error();
2056|      m_prevZoom = m_Zoom;
2057|    }
2058|
2059|    m_prevX0 = 0.0f;  m_prevY0 = 0.0f;
2060|
2061|    render->Release();
2062|  }
2063|
2064|  m_ZoomSwitchZoom = 100;
2065|  m_ZoomSwitchOffset.x = 0;  m_ZoomSwitchOffset.y = 0;
2066|  m_ZoomSwitchMode = CChildView_ZoomNormal;
2067|  m_ZoomSwitchPage = 1;
2068|}
2069|
2070|
2071| 
2072|/***********************************************************************
2073|  18. <<< [CChildView::GetDrawParam] 描画パラメータを取得する >>> 
2074|【補足】
2075|・描画するときに各図形にこのパラメータを渡します。
2076|・本関数は、画面描画用です。プリンタ用は、CChildView::PrintSub で
2077|  補正しています。
2078|************************************************************************/
2079|void   CChildView::GetDrawParam( CadPrim_DrawParam* p )
2080|{
2081|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
2082|  POINT  pt = GetScrollPosition();
2083|
2084|  p->zoom = m_Zoom;
2085|  p->x0 = pt.x;  p->y0 = pt.y;
2086|  p->bWhiteToBGColor = false;
2087|  p->bDrawHandle = ( ( ! m_bDrag && ! m_bDblDrag ) || m_bInDragPlay ) && ! m_bEditorEnable;
2088|  p->bPrint = false;
2089|  p->clip_left = 0;
2090|  p->clip_right = app->m_file.m_Canvas.m_Width * p->zoom / 100;
2091|  p->clip_top = 0;
2092|  p->clip_bottom = app->m_file.m_Canvas.m_Height * p->zoom / 100;
2093|  p->iPage = -1;
2094|}
2095|
2096|
2097| 
2098|/***********************************************************************
2099|  19. <<< [CChildView::DrawBackBitmap] 背景をビットマップにキャッシュする >>> 
2100|【補足】
2101|・背景は毎回描画しないで、背景の編集やロードが終わったときに描画します。
2102|・現在のページ(CSVGCatApp::ChgPage)を、背景ページから他のページに
2103|  移るときに描画します。 この関数は、CSVGCatApp::ChgPage から呼ばれます。
2104|・ズームしたときも呼ばれます。
2105|************************************************************************/
2106|#ifdef  SVGCAT_USES_BACKBUF  /* DDB を作成するのに時間がかかるためバッファリングしないようにした */
2107|
2108|void  CChildView::DrawBackBitmap()
2109|{
2110|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
2111|  CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
2112|
2113|  if ( ! m_bEnableOnPaint )  return;
2114|
2115|  if ( app->m_file.m_StartPageNum > 0 ) {
2116|    m_bBackBitmap = false;
2117|    return;
2118|  }
2119|  else {
2120|    CClientDC    dc(this);
2121|    CDC*         bmpDC;
2122|    RECT  rect;
2123|    int   pageNum;
2124|    char  path[_MAX_PATH];
2125|
2126|    GetClientRect( &rect );
2127|
2128|    m_BackBitmapWidth = rect.right - rect.left + 1;
2129|    m_BackBitmapHeight = rect.bottom - rect.top + 1;
2130|
2131|    if ( m_bBackBitmap )
2132|      WinX_DDBmp_finish( &m_BackBmp );
2133|
2134|    sprintf( path, "system\\work\\back_%08X.ddb", (long)frame->m_hWnd );
2135|    StrX_getExeFullPath( path, path, sizeof(path) );
2136|    WinX_DDBmp_init( &m_BackBmp, path );
2137|
2138|    /* 背景バッファの内容を更新する */
2139|    if ( 0 && m_backSurf != NULL ) {  /* Draw 中に呼ばれると 2重DCのエラーになるため却下 */
2140|      HDC  hdc;
2141|      HRESULT  hr;
2142|
2143|      hr = m_backSurf->GetDC( &hdc );  if ( hr != DD_OK ) {WD(hr);error();}
2144|      bmpDC = CDC::FromHandle( WinX_DDBmp_openForWrite( &m_BackBmp, hdc,
2145|        m_BackBitmapWidth, m_BackBitmapHeight ) );
2146|      hr = m_backSurf->ReleaseDC( hdc );  if ( hr != DD_OK ) error();
2147|    }
2148|    else {
2149|    //  bmpDC = CDC::FromHandle( WinX_DDBmp_openForWrite( &m_BackBmp, dc.m_hDC,
2150|    //    m_BackBitmapWidth, m_BackBitmapHeight ) );
2151|    }
2152|
2153|    m_bEnableOnPaint = false;  /* ChgToBackPage でここに再帰しないため */
2154|    pageNum = app->m_file.m_CurrentPageNum;
2155|    if ( pageNum != 0 )  app->ChgToBackPage( &app->m_file );
2156|    m_bBackBitmap = false;  /* 背景を描画するので、背景バッファは描画しない */
2157|
2158|    DrawAll( &m_BackBitmapDC, false, true, true, true );
2159|
2160|    if ( pageNum != 0 )  app->ChgToBackPage( &app->m_file );
2161|    m_BackBitmapOffset = GetScrollPosition();
2162|    m_bEnableOnPaint = true;
2163|    //    bmpDC->Detach();
2164|
2165|    /* 背景バッファの内容を保存する */
2166|    //WinX_DDBmp_closeForWrite( &m_BackBmp );
2167|
2168|    m_bBackBitmap = true;
2169|  }
2170|}
2171|#else
2172|void  CChildView::DrawBackBitmap(){}
2173|#endif
2174|
2175|
2176| 
2177|/***********************************************************************
2178|  20. <<< [CChildView::DrawOutOfCanvas] キャンバスの外を描画する >>> 
2179|【引数】
2180|  ・CDC*  dc;  デバイス・コンテキスト
2181|************************************************************************/
2182|void  CChildView::DrawOutOfCanvas( CDC* dc )
2183|{
2184|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
2185|  CPoint  pt = GetScrollPosition();
2186|  CRect   rect;
2187|  CadPrim_DrawParam  p;
2188|
2189|  GetDrawParam( &p );
2190|  GetClientRect(&rect);
2191|  pt.x -= m_MinusOffset.x;  pt.y -= m_MinusOffset.y;
2192|  app->m_file.m_Canvas.DrawOutSide( dc, &pt, &p, rect.right, rect.bottom );
2193|
2194|
2195|  /* 用紙サイズを描画する */
2196|  if ( m_bDrag != NULL && m_HoldPrim == &app->m_file.m_Canvas ) {
2197|    CPen  dashPen( PS_DOT, 1, RGB(0,0,0) );
2198|    CPen* old;
2199|    CFont font;
2200|    CFont* oldFont;
2201|    RECT  rc;
2202|    int  w = Canvas_A4_W * m_Zoom/100;
2203|    int  h = Canvas_A4_H * m_Zoom/100;
2204|
2205|    font.CreatePointFont( 100, "Times New Roman", dc );
2206|    old = dc->SelectObject( &dashPen );
2207|    oldFont = dc->SelectObject( &font );
2208|    dc->SetBkMode( OPAQUE );
2209|    dc->SetBkColor( RGB( 0xFF,0xFF,0xFF ) );
2210|
2211|    dc->MoveTo( w - p.x0,  0 - p.y0 );
2212|    dc->LineTo( w - p.x0,  h - p.y0 );
2213|    dc->LineTo( 0 - p.x0,  h - p.y0 );
2214|    dc->MoveTo( w+1 - p.x0,  0   - p.y0 );
2215|    dc->LineTo( w+1 - p.x0,  h+1 - p.y0 );
2216|    dc->LineTo( 0   - p.x0,  h+1 - p.y0 );
2217|
2218|    rc.left = rc.right = 650*m_Zoom/100 - p.x0;
2219|    rc.top = rc.bottom = 4;
2220|    dc->DrawText( "A4", -1, &rc, DT_LEFT | DT_SINGLELINE | DT_TOP |
2221|      DT_NOCLIP | DT_NOPREFIX | DT_EXTERNALLEADING );
2222|
2223|    dc->SelectObject( old );
2224|  }
2225|}
2226|
2227|
2228| 
2229|/***********************************************************************
2230|  21. <<< [CChildView::RedrawWidthArea] 複数選択用の矩形を描画する >>> 
2231|【補足】
2232|・x1,y1,x2,y2 は、キャンバス座標です。
2233|************************************************************************/
2234|void  CChildView::RedrawWidthArea( CDC* dc, int x1, int y1, int x2, int y2 )
2235|{
2236|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
2237|  CRgn  rgn;
2238|  CBrush  hatchBrush( HS_FDIAGONAL, GetSysColor( COLOR_HIGHLIGHT ) );
2239|  CBrush  nullBrush( NULL_BRUSH );
2240|  CBrush* oldBrush;
2241|  CPen    pen( PS_DASHDOT, 1, (COLORREF)GetSysColor( COLOR_HIGHLIGHT ) );
2242|  CPen*   oldPen;
2243|  CPoint  pt = GetScrollPosition();
2244|  int     w = app->m_file.m_Canvas.m_Width * m_Zoom / 100;
2245|  int     h = app->m_file.m_Canvas.m_Height * m_Zoom / 100;
2246|  CRect   rect;
2247|  ERRORS_FUNC_CPP_VAR( CChildView_RedrawWidthArea );
2248|  ERRORS_FUNC_START_CPP( CChildView_RedrawWidthArea );
2249|
2250|  nullBrush.CreateStockObject( NULL_BRUSH );
2251|
2252|  x1 = x1 * m_Zoom / 100 - pt.x;
2253|  y1 = y1 * m_Zoom / 100 - pt.y;
2254|  x2 = x2 * m_Zoom / 100 - pt.x;
2255|  y2 = y2 * m_Zoom / 100 - pt.y;
2256|
2257|  /* 網掛け */
2258|  rgn.CreateRectRgn( 0, 0,  w,  h );
2259|  dc->SelectClipRgn( &rgn );
2260|  dc->SetBkMode( TRANSPARENT );
2261|  oldBrush = dc->SelectObject( &hatchBrush );
2262|  dc->Rectangle( x1, y1, x2, y2 );
2263|
2264|
2265|  /* 境界線 */
2266|  dc->SetBkMode( OPAQUE );
2267|  dc->SetBkColor( ~GetSysColor( COLOR_HIGHLIGHT ) & 0xFFFFFF );
2268|  dc->SelectObject( &nullBrush );
2269|  oldPen = dc->SelectObject( &pen );
2270|  dc->Rectangle( x1, y1, x2, y2 );
2271|
2272|  dc->SelectClipRgn( NULL );
2273|  dc->SelectObject( oldBrush );
2274|  dc->SelectObject( oldPen );
2275|
2276|
2277|  ERRORS_FUNC_END_CPP( CChildView_RedrawWidthArea );
2278|}
2279|
2280|
2281| 
2282|/***********************************************************************
2283|  22. <<< [CChildView::RedrawZoomArea] ズームする範囲を示す領域を描画する >>> 
2284|************************************************************************/
2285|void  CChildView::RedrawZoomArea( CDC* dc, int x, int y )
2286|{
2287|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
2288|  CPoint  pt = GetScrollPosition();
2289|  int     x1,y1, x2,y2;  /* Bitmap座標 */
2290|  int     X1,Y1, X2,Y2;  /* クライアント領域の座標 */
2291|  int     w = app->m_file.m_Canvas.m_Width * m_Zoom / 100 - pt.x;
2292|  int     h = app->m_file.m_Canvas.m_Height * m_Zoom / 100 - pt.y;
2293|  CRect   rect;
2294|  HDC     hdc;
2295|  ERRORS_FUNC_CPP_VAR( CChildView_RedrawZoomArea );
2296|  ERRORS_FUNC_START_CPP( CChildView_RedrawZoomArea );
2297|
2298|  GetClientRect( &rect );
2299|  if ( w > rect.right )  w = rect.right;
2300|  if ( h > rect.bottom )  h = rect.bottom;
2301|
2302|  x1 = ( x * m_Zoom / 100 ) - ( rect.right  * m_Zoom / m_ZoomNext / 2 );
2303|  y1 = ( y * m_Zoom / 100 ) - ( rect.bottom * m_Zoom / m_ZoomNext / 2 );
2304|  x2 = ( x * m_Zoom / 100 ) + ( rect.right  * m_Zoom / m_ZoomNext / 2 );
2305|  y2 = ( y * m_Zoom / 100 ) + ( rect.bottom * m_Zoom / m_ZoomNext / 2 );
2306|  X1 = x1 - pt.x;
2307|  Y1 = y1 - pt.y;
2308|  X2 = x2 - pt.x;
2309|  Y2 = y2 - pt.y;
2310|
2311|  if ( X1 < 0 )  { x2 += -X1;  X2 += -X1;  x1 = pt.x;  X1 = 0; }
2312|  if ( Y1 < 0 )  { y2 += -Y1;  Y2 += -Y1;  y1 = pt.y;  Y1 = 0; }
2313|  if ( X2 > w - 1 )
2314|    { X1 -= X2 - w;  x1 = X1 + pt.x;  X2 = w;  x2 = X2 + pt.x; }
2315|  if ( Y2 > h - 1 )
2316|    { Y1 -= Y2 - h;  y1 = Y1 + pt.y;  Y2 = h;  y2 = Y2 + pt.y; }
2317|
2318|  /* 表示画面へ転送する */
2319|  hdc = WinX_DDBmp_openForRead( &m_HatchedCanvas, dc->m_hDC );
2320|  BitBlt( dc->m_hDC, 0,   0, w,       Y1,      hdc,  0,  0, SRCCOPY );
2321|  BitBlt( dc->m_hDC, 0,  Y1, X1,      Y2 - Y1, hdc,  0, Y1, SRCCOPY );
2322|  BitBlt( dc->m_hDC, X1, Y1, X2 - X1, Y2 - Y1, m_BitmapDC.m_hDC,  X1, Y1, SRCCOPY );
2323|  BitBlt( dc->m_hDC, X2, Y1, w - X2,  Y2 - Y1, hdc, X2, Y1, SRCCOPY );
2324|  BitBlt( dc->m_hDC, 0,  Y2, w,       h - Y2,  hdc,  0, Y2, SRCCOPY );
2325|  WinX_DDBmp_closeForRead( &m_HatchedCanvas );
2326|
2327|  ERRORS_FUNC_END_CPP( CChildView_RedrawZoomArea );
2328|}
2329|
2330|
2331| 
2332|/***********************************************************************
2333|  23. <<< [CChildView::SetDrawnParam] 描画して得られる属性を設定する >>> 
2334|【補足】
2335|・Text_Box にある、描画することで得られる属性を設定して、保存できるようにします。
2336|************************************************************************/
2337|void  CChildView::SetDrawnParam( ListX* prims )
2338|{
2339|  ListX_ElemX*  pPrim;
2340|  CadPrim_DrawParam  p;
2341|  int  type;
2342|
2343|  GetDrawParam( &p );
2344|  for ( ListX_forEach( prims, &pPrim, ListX_ElemX ) ) {
2345|    type = ((CadPrim*)pPrim->p)->GetTypeID();
2346|    if ( type == Text_Box_TypeID || type == Line_Corner_TypeID )
2347|      ((CadPrim*)pPrim->p)->Draw( &m_MinBitmapDC, &p );
2348|  }
2349|}
2350| 
2351|/***********************************************************************
2352|  24. <<< [CChildView::SetScrollSize] スクロールの範囲を計算する >>> 
2353|************************************************************************/
2354|void  CChildView::SetScrollSize()
2355|{
2356|  CSVGCatApp*   app;// = (CSVGCatApp*)AfxGetApp();
2357|  RECT  rc;
2358|  HRESULT  hr;
2359|  int  ink_w, ink_h;
2360|  POINT  pt;
2361|
2362|  app = (CSVGCatApp*)AfxGetApp();
2363|  SetZoomByCulc();
2364|  GetClientRect( &rc );
2365|  pt = GetScrollPosition();
2366|
2367|  if ( m_ZoomMode == CChildView_ZoomNormal ) {
2368|    CSize  size2( (app->m_file.m_Canvas.m_Width) * m_Zoom / 100 + 6,
2369|             (app->m_file.m_Canvas.m_Height) * m_Zoom / 100 + 6 );
2370|
2371|    /* ドラッグ中は小さくしない */
2372|    if ( m_bDrag ) {
2373|      CSize  prevSize = GetTotalSize();
2374|
2375|      if ( size2.cx < prevSize.cx )  size2.cx = prevSize.cx;
2376|      if ( size2.cy < prevSize.cy )  size2.cy = prevSize.cy;
2377|    }
2378|
2379|    if ( size2.cx < rc.right )  size2.cx = 0;
2380|    if ( size2.cy < rc.bottom )  size2.cy = 0;
2381|      /* 最大化したとき、0 にしても何故か ScrollToPosition でスクロールできてしまうが、*/
2382|      /* GetTotalSize で 0 が返るようになるため ScrollToPosition を使わない判定に使える */
2383|
2384|    SetScrollSizes( MM_TEXT, size2,
2385|      CSize( rc.right, rc.bottom ), CSize( rc.right / 8, rc.bottom / 8 ) );
2386|  }
2387|  else if ( m_ZoomMode == CChildView_ZoomWhole ) {
2388|    SetScrollSizes( MM_TEXT, CSize( 0,0 ) );
2389|  }
2390|  else {  /* CChildView_ZoomWidth */
2391|    CSize  size2( 0, (app->m_file.m_Canvas.m_Height) * m_Zoom / 100 + 6 );
2392|
2393|    if ( size2.cy < rc.bottom )  size2.cy = 0;
2394|      /* 最大化から戻したしたとき、0 にしても何故か ScrollToPosition でスクロールできてしまうが、*/
2395|      /* GetTotalSize で 0 が返るようになるため ScrollToPosition を使わない判定に使える */
2396|
2397|    SetScrollSizes( MM_TEXT, size2,
2398|      CSize( rc.right, rc.bottom ), CSize( rc.right / 8, rc.bottom / 8 ) );
2399|  }
2400|
2401|  if ( m_InkRectangle != NULL ) {
2402|    ink_w = app->m_file.m_Canvas.m_Width * m_Zoom / 100 - pt.x;
2403|    ink_h = app->m_file.m_Canvas.m_Height * m_Zoom / 100 - pt.y;
2404|    if ( ink_w > rc.right )  ink_w = rc.right;
2405|    if ( ink_h > rc.bottom )  ink_h = rc.bottom;
2406|    hr = m_InkRectangle->SetRectangle( /*top*/ 0, /*left*/ 0, /*bottom*/ ink_h , /*right*/ ink_w );
2407|    if ( hr != 0 )  error();
2408|  }
2409|  if ( m_InkOverlay != NULL ) {
2410|    m_InkOverlay->SetWindowInputRectangle( m_InkRectangle );
2411|    if ( hr != 0 )  error();
2412|  }
2413|}
2414|
2415|
2416| 
2417|/***********************************************************************
2418|  25. <<< [CChildView::ResetScrollPos] スクロールの範囲を原点に戻す >>> 
2419|************************************************************************/
2420|void  CChildView::ResetScrollPos()
2421|{
2422|  POINT  pt;
2423|
2424|  pt.x = 0;  pt.y = 0;
2425|  ScrollToPosition( pt );
2426|}
2427| 
2428|/***********************************************************************
2429|  26. <<< [CChildView::StartCountForDragScroll] ドラッグ・スクロールのカウントダウンを始める >>> 
2430|************************************************************************/
2431|void  CChildView::StartCountForDragScroll()
2432|{
2433|  RECT  noScrollArea;
2434|  POINT  point;
2435|
2436|  GetCursorPos( &point );
2437|  GetWindowRect( &noScrollArea );
2438|  noScrollArea.left += 32;  noScrollArea.right -= 32;
2439|  noScrollArea.top += 32;  noScrollArea.bottom -= 32;
2440|
2441|  if ( point.x < noScrollArea.left || point.x > noScrollArea.right ||
2442|       point.y < noScrollArea.top || point.y > noScrollArea.bottom ) {
2443|    m_MsgToDragScroller = 2;
2444|  }
2445|  else {
2446|    EndDragScroll();
2447|  }
2448|}
2449|
2450|/***********************************************************************
2451|  27. <<< [CChildView::EndDragScroll] ドラッグ・スクロールをやめる >>>
2452|************************************************************************/
2453|void  CChildView::EndDragScroll()
2454|{
2455|  m_MsgToDragScroller = 0;
2456|}
2457|
2458| 
2459|/***********************************************************************
2460|  28. <<< [CChildView::OnDragScrollTiming] ドラッグ・スクロールする >>> 
2461|【補足】
2462|・スコープモードの自動消去からもどる処理もここで行います。
2463|************************************************************************/
2464|DWORD WINAPI CChildView_DragScroller( CChildView* m )
2465|{
2466|  CSVGCatApp*   app = (CSVGCatApp*)AfxGetApp();
2467|  CMainFrame*   frame = (CMainFrame*)app->m_pMainWnd; //(CMainFrame*)m->GetParent()->GetParent();
2468|
2469|	while(1) { /* 無限ループするスレッド */
2470|    switch ( m->m_MsgToDragScroller ) {
2471|      case 0:
2472|        Sleep( 100 );
2473|
2474|        /* スコープモードで、カーソルが上に来たらウィンドウを消す。離れたら表示する */
2475|        if ( frame->m_bScopeHiding ) {
2476|          if ( ! frame->m_bScopeHidingCancel && ! frame->m_bActivated ) {
2477|            frame->m_bScopeHiding = false;
2478|            frame->ShowWindow(SW_HIDE);
2479|            frame->m_bScopeHide = true;
2480|          }
2481|          else {
2482|            RECT  rect;
2483|            POINT  pt;
2484|
2485|            m->GetWindowRect( &rect );
2486|            GetCursorPos( &pt );
2487|            if ( pt.x < rect.left || pt.x > rect.right || pt.y < rect.top || pt.y > rect.bottom ) {
2488|              frame->m_bScopeHiding = false;
2489|              frame->m_bScopeHidingCancel = false;
2490|            }
2491|          }
2492|        }
2493|        else if ( frame->m_bScopeHide ) {
2494|          RECT  rect;
2495|          POINT  pt;
2496|
2497|          m->GetWindowRect( &rect );
2498|          GetCursorPos( &pt );
2499|          Sleep( 400 );
2500|          if ( pt.x < rect.left || pt.x > rect.right || pt.y < rect.top || pt.y > rect.bottom ) {
2501|            frame->ShowWindow(SW_SHOW);
2502|            frame->m_bScopeHide = false;
2503|          }
2504|        }
2505|        break;
2506|      case 1:  goto  finish;
2507|      case 2: {
2508|        POINT  point;
2509|
2510|        Sleep( 200 );
2511|
2512|        frame->SendMessage( WM_COMMAND, CMainFrame_Scrolling, NULL );
2513|        GetCursorPos( &point );
2514|        SetCursorPos( point.x, point.y );  /* m->OnMouseMove( 0, point ); が呼ばれる */
2515|        break;
2516|      }
2517|    }
2518|	}
2519|finish:
2520|	return 0;
2521|}
2522|
2523|void  CChildView::OnDragScrollTiming()
2524|{
2525|  RECT   windowArea;
2526|  CSize  scrollSize;
2527|  RECT   noScrollArea;
2528|  POINT  point;
2529|  POINT  pt = GetScrollPosition();
2530|  int    dx, dy;
2531|
2532|  GetWindowRect( &windowArea );
2533|  scrollSize = GetTotalSize();
2534|  noScrollArea.left = windowArea.left + 32;
2535|  noScrollArea.right = windowArea.right - 32;
2536|  noScrollArea.top = windowArea.top + 32;
2537|  noScrollArea.bottom = windowArea.bottom - 32;
2538|  GetCursorPos( &point );
2539|
2540|  dx = 4;  dy = 4;
2541|  if ( scrollSize.cy + 4 > windowArea.bottom - windowArea.top )  dx += 17;
2542|  if ( scrollSize.cx + 4 > windowArea.right - windowArea.left )  dy += 17;
2543|
2544|  if ( scrollSize.cx + dx > windowArea.right - windowArea.left ) {
2545|    if ( point.x < noScrollArea.left )   pt.x -= 32;
2546|    else if ( point.x > noScrollArea.right )  { pt.x += 32;  SetScrollSize(); }
2547|  }
2548|
2549|  if ( scrollSize.cy + dy > windowArea.bottom - windowArea.top ) {
2550|    if ( point.y < noScrollArea.top )  pt.y -= 32;
2551|    else if ( point.y > noScrollArea.bottom ) { pt.y += 32;  SetScrollSize(); }
2552|  }
2553|
2554|  ScrollToPosition( pt );
2555|
2556|  {
2557|    CClientDC  dc( this );
2558|    DrawOutOfCanvas( &dc );
2559|  }
2560|}
2561|
2562|
2563| 
2564|/***********************************************************************
2565|  29. <<< [CChildView_Blinker] キャレットを点滅するスレッド >>> 
2566|************************************************************************/
2567|DWORD WINAPI CChildView_Blinker( CChildView* m )
2568|{
2569|#ifdef  SvgCats_DirectInput
2570|  CadPrim_DrawParam  p;
2571|
2572|	while(1) { /* 無限ループするスレッド */
2573|    switch ( m->m_MsgToBlinker ) {
2574|      case 0:
2575|        Sleep( GetCaretBlinkTime() );
2576|
2577|        {
2578|          CClientDC  dc( m );
2579|          m->GetDrawParam( &p );
2580|          if ( m->m_bEditorEnable )  m->m_Editor->OnBlinkTiming( &dc, &p );
2581|        }
2582|        break;
2583|      case 1:  goto  finish;
2584|    }
2585|	}
2586|finish:
2587|#endif
2588|	return 0;
2589|}
2590| 
2591|/***********************************************************************
2592|  30. <<< [CChildView::OnMouseWheel] マウスホイールを回転させたときの処理 >>> 
2593|************************************************************************/
2594|BOOL CChildView::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
2595|{
2596|  CSVGCatApp*   app = (CSVGCatApp*)AfxGetApp();
2597|  CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
2598|  CPoint  p = GetScrollPosition();
2599|  CPoint  p2;
2600|  CSize   scrollSize = GetTotalSize();
2601|  RECT  rc;
2602|
2603|  frame->m_bScopeHidingCancel = true;
2604|
2605|  /* ツリーの上にマウスがあったらツリーをスクロールする */
2606|  frame->m_Left->GetClientRect( &rc );  frame->m_Left->ClientToScreen( &rc );
2607|  if ( rc.left <= pt.x && pt.x <= rc.right && rc.top <= pt.y && pt.y <= rc.bottom ) {
2608|    frame->m_wndSplitter.SetActivePane( 0, 0, frame->m_Left );
2609|    return  frame->m_Left->OnMouseWheel(nFlags, zDelta, pt);
2610|  }
2611|  frame->m_wndSplitter.SetActivePane( 0, 0, this );
2612|
2613|
2614|  /* スクロールする */
2615|  zDelta /= 2;
2616|
2617|  if ( scrollSize.cy != 0 ) {
2618|
2619|    p.y -= zDelta;
2620|    ScrollToPosition( p );
2621|
2622|    p2 = GetScrollPosition();
2623|  }
2624|  if ( scrollSize.cy == 0 || p2.y == p.y + zDelta ) {
2625|    if ( zDelta < 0 )  frame->OnNextPage();
2626|    else if ( app->m_file.m_CurrentPageNum > 1 ) {
2627|      CSize  end;
2628|
2629|      frame->OnPrevPage();
2630|      end = GetTotalSize();
2631|      p.y = end.cy;
2632|      ScrollToPosition( p );
2633|    }
2634|  }
2635|
2636|	return CScrollView ::OnMouseWheel(nFlags, zDelta, pt);
2637|}
2638|
2639|void CChildView::OnNextPageScroll()
2640|{
2641|  CSVGCatApp*   app = (CSVGCatApp*)AfxGetApp();
2642|  CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
2643|  CPoint  p = GetScrollPosition();
2644|  CPoint  p2;
2645|  CSize   scrollSize = GetTotalSize();
2646|  RECT  clientRc;
2647|  int  zDelta;
2648|
2649|  GetClientRect( &clientRc );
2650|  zDelta = -( clientRc.bottom - 32 );
2651|
2652|  if ( scrollSize.cy != 0 ) {
2653|
2654|    p.y -= zDelta;
2655|    ScrollToPosition( p );
2656|
2657|    p2 = GetScrollPosition();
2658|  }
2659|  if ( scrollSize.cy == 0 || p2.y == p.y + zDelta ) {
2660|    if ( zDelta < 0 )  frame->OnNextPage();
2661|    else if ( app->m_file.m_CurrentPageNum > 1 ) {
2662|      CSize  end;
2663|
2664|      frame->OnPrevPage();
2665|      end = GetTotalSize();
2666|      p.y = end.cy;
2667|      ScrollToPosition( p );
2668|    }
2669|  }
2670|}
2671|
2672|void CChildView::OnPrevPageScroll()
2673|{
2674|  CSVGCatApp*   app = (CSVGCatApp*)AfxGetApp();
2675|  CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
2676|  CPoint  p = GetScrollPosition();
2677|  CPoint  p2;
2678|  CSize   scrollSize = GetTotalSize();
2679|  RECT  clientRc;
2680|  int  zDelta;
2681|
2682|  GetClientRect( &clientRc );
2683|  zDelta = +( clientRc.bottom - 32 );
2684|
2685|  if ( scrollSize.cy != 0 ) {
2686|
2687|    p.y -= zDelta;
2688|    ScrollToPosition( p );
2689|
2690|    p2 = GetScrollPosition();
2691|  }
2692|  if ( scrollSize.cy == 0 || p2.y == p.y + zDelta ) {
2693|    if ( zDelta < 0 )  frame->OnNextPage();
2694|    else if ( app->m_file.m_CurrentPageNum > 1 ) {
2695|      CSize  end;
2696|
2697|      frame->OnPrevPage();
2698|      end = GetTotalSize();
2699|      p.y = end.cy;
2700|      ScrollToPosition( p );
2701|    }
2702|  }
2703|}
2704|
2705|
2706| 
2707|/***********************************************************************
2708|  31. <<< [CChildView::OnSize] ウィンドウのサイズを変更したときの処理 >>> 
2709|************************************************************************/
2710|void CChildView::OnSize(UINT nType, int cx, int cy)
2711|{
2712|  CScrollView ::OnSize(nType, cx, cy);
2713|  HRESULT  hr;
2714|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
2715|
2716|  if ( Errors_bExiting )  return;
2717|
2718|  {
2719|    CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
2720|
2721|    if ( frame->m_bScopeMode && frame->IsZoomed() ) {
2722|      frame->ShowWindow( SW_RESTORE );
2723|      frame->PostMessage( WM_COMMAND, ID_ScopeMode, 0 );
2724|    }
2725|  }
2726|
2727|  if ( m_InkRectangle != NULL ) {
2728|
2729|    hr = m_InkRectangle->SetRectangle( /*top*/ 0, /*left*/ 0,
2730|      /*bottom*/ app->m_file.m_Canvas.m_Height * m_Zoom / 100, /*right*/ app->m_file.m_Canvas.m_Width * m_Zoom / 100 );
2731|    if ( hr != 0 )  error();
2732|
2733|    m_InkOverlay->SetWindowInputRectangle( m_InkRectangle );
2734|    if ( hr != 0 )  error();
2735|  }
2736|
2737|  SetScrollSize();
2738|
2739|  m_bBitmap = false;
2740|}
2741|
2742| 
2743|/***********************************************************************
2744|  32. <<< [CChildView::Zoom] ズームする >>> 
2745|************************************************************************/
2746|void  CChildView::Zoom( int zoom )
2747|{
2748|  CSVGCatApp*   app = (CSVGCatApp*)AfxGetApp();
2749|  CMainFrame*   frame = (CMainFrame*)GetParent()->GetParent();
2750|  CPoint  pt = GetScrollPosition();
2751|  RECT   rect;
2752|  CadPrim_DrawParam  p;
2753|
2754|  ERRORS_FUNC_CPP_VAR( CChildView_Zoom );
2755|  ERRORS_FUNC_START_CPP( CChildView_Zoom );
2756|
2757|  GetClientRect( &rect );
2758|
2759|  /* 拡大した結果が画面の 5/4 より大きいときは、拡大する位置を選択するモードへ */
2760|  if ( zoom > m_Zoom ) {
2761|    if ( app->m_file.m_Canvas.m_Width * zoom / 100 > rect.right * 5 / 4  ||
2762|         app->m_file.m_Canvas.m_Height * zoom / 100 > rect.bottom * 5 / 4 ) {
2763|      CClientDC  dc( this );
2764|      CPen    pen( PS_NULL, 0, (COLORREF)0 );
2765|      CPen*   oldPen;
2766|      CBrush  brush1( HS_FDIAGONAL, RGB(0xFF,0xFF,0xFF) );
2767|      CBrush  brush2( HS_BDIAGONAL, RGB(0x00,0x00,0x00) );
2768|      CBrush* oldBrush;
2769|      Text_Box  msg;
2770|      CPoint  pt = GetScrollPosition();
2771|      int     w = app->m_file.m_Canvas.m_Width * m_Zoom / 100 - pt.x;
2772|      int     h = app->m_file.m_Canvas.m_Height * m_Zoom / 100 - pt.y;
2773|      CRect   rect;
2774|
2775|      m_ZoomNext = zoom;
2776|      if ( frame->m_mode != CMainFrame_Zooming ) {
2777|        m_ModeBeforeZoom = frame->m_mode;
2778|        frame->OnSelect();
2779|        frame->m_mode = CMainFrame_Zooming;
2780|      }
2781|
2782|
2783|      GetClientRect( &rect );
2784|      if ( w > rect.right )  w = rect.right;
2785|      if ( h > rect.bottom )  h = rect.bottom;
2786|
2787|      DrawAll( &m_BitmapDC, false );
2788|
2789|      /* m_HatchedCanvas にキャンバス全体に編みかけをした画像を作成する */
2790|      {
2791|        CDC*   hdc;
2792|
2793|        hdc = CDC::FromHandle( WinX_DDBmp_openForWrite( &m_HatchedCanvas, dc.m_hDC, w, h ) );
2794|
2795|        DrawAll( hdc, false );
2796|        hdc->SetBkMode( TRANSPARENT );
2797|        oldPen = hdc->SelectObject( &pen );
2798|        oldBrush = hdc->SelectObject( &brush1 );
2799|        hdc->Rectangle( 0, 0, w, h );  /* Brash 付き塗り潰しは遅いかも */
2800|        hdc->SelectObject( &brush2 );
2801|        hdc->Rectangle( 0, 0, w, h );
2802|        hdc->SelectObject( oldBrush );
2803|        hdc->SelectObject( &oldPen );
2804|
2805|        dc.BitBlt( 0, 0, w, h,  hdc, 0, 0, SRCCOPY );
2806|
2807|        hdc->Detach();
2808|        WinX_DDBmp_closeForWrite( &m_HatchedCanvas );
2809|      }
2810|
2811|      /* ガイド文字列を描画する */
2812|      dc.SetBkMode( OPAQUE );
2813|      if ( app->m_bJapanese )  msg.m_Text.LoadString( IDS_ClickOnZoom );
2814|      else  msg.m_Text.LoadString( IDS_ClickOnZoom_E );
2815|      msg.m_CenterX = rect.right / 3 + pt.x;
2816|      msg.m_Y = rect.bottom / 3 + pt.y;
2817|      msg.m_FillColor = RGB( 0xFF, 0xFF, 0x00 );
2818|      GetDrawParam( &p );  p.zoom = 100;
2819|      msg.Draw( &dc, &p );
2820|
2821|      msg.m_CenterX -= 30;
2822|      msg.m_Text.Format( "x%d", zoom / 100 );
2823|      msg.Draw( &dc, &p );
2824|
2825|      ERRORS_FUNC_END_CPP( CChildView_Zoom );
2826|      return;
2827|    }
2828|  }
2829|  else {
2830|    if ( frame->m_mode == CMainFrame_Zooming )    /* 拡大を指定している途中で戻したとき */
2831|      frame->m_mode = m_ModeBeforeZoom;
2832|  }
2833|
2834|  /* 縮小するときは、画面の中心位置を変えないようにする */
2835|  if ( zoom < m_Zoom ) {
2836|    POINT  point;
2837|    CClientDC  dc( this );
2838|    CPen    pen( PS_NULL, 0, (COLORREF)0 );
2839|    CPen*   oldPen;
2840|    CBrush  brush( GetSysColor( COLOR_APPWORKSPACE ) );
2841|    CBrush* oldBrush;
2842|    int     w, h;
2843|    CRgn  clip;
2844|
2845|    m_ZoomNext = m_Zoom;  /* 前の拡大率 */
2846|
2847|    point.x = ( pt.x - rect.right / 2 ) * zoom / m_Zoom;
2848|    point.y = ( pt.y - rect.bottom / 2 ) * zoom / m_Zoom;
2849|
2850|    /* 以下はガイド表示 */
2851|    oldPen = dc.SelectObject( &pen );  /* ScrollToPosition で自動的にスクロール描画してちらつくため */
2852|    oldBrush = dc.SelectObject( &brush );
2853|    dc.Rectangle( 0, 0, app->m_file.m_Canvas.m_Width * m_Zoom / 100 + 1,
2854|                       app->m_file.m_Canvas.m_Height * m_Zoom / 100 + 1 );
2855|    dc.SelectObject( &oldPen );
2856|    dc.SelectObject( &oldBrush );
2857|    m_Zoom = zoom;
2858|    ScrollToPosition( point );
2859|    SetScrollSize();
2860|    point = GetScrollPosition();
2861|
2862|    DrawBackBitmap();
2863|    DrawAll( &m_BitmapDC, true );
2864|
2865|    w = app->m_file.m_Canvas.m_Width * zoom / 100 - point.x;
2866|    h = app->m_file.m_Canvas.m_Height * zoom / 100 - point.y;
2867|    if ( w > rect.right )  w = rect.right;
2868|    if ( h > rect.bottom )  h = rect.bottom;
2869|    DrawOutOfCanvas( &dc );
2870|
2871|    {
2872|      CDC*   hdc;
2873|
2874|      hdc = CDC::FromHandle( WinX_DDBmp_openForWrite( &m_HatchedCanvas, dc.m_hDC, w, h ) );
2875|
2876|      DrawAll( hdc, true );
2877|      hdc->SetBkMode( TRANSPARENT );
2878|      clip.CreateRectRgn( 0, 0,  app->m_file.m_Canvas.m_Width * m_Zoom / 100,
2879|        app->m_file.m_Canvas.m_Height * m_Zoom / 100 );
2880|      hdc->SelectClipRgn( &clip );
2881|
2882|      oldPen = hdc->SelectObject( &pen );
2883|      oldBrush = hdc->SelectObject( &brush );
2884|      hdc->Rectangle( 0, 0, app->m_file.m_Canvas.m_Width * m_Zoom / 100 + 1, app->m_file.m_Canvas.m_Height * m_Zoom / 100 + 1 );
2885|      hdc->Rectangle( 0, 0, app->m_file.m_Canvas.m_Width * m_Zoom / 100 + 1, app->m_file.m_Canvas.m_Height * m_Zoom / 100 + 1 );
2886|      hdc->SelectObject( oldBrush );
2887|      hdc->SelectObject( &oldPen );
2888|
2889|      hdc->SelectClipRgn( NULL );
2890|
2891|      hdc->Detach();
2892|      WinX_DDBmp_closeForWrite( &m_HatchedCanvas );
2893|    }
2894|
2895|    RedrawZoomArea( &dc, ( pt.x + rect.right / 2 ) * 100 / m_ZoomNext,
2896|      ( pt.y + rect.bottom / 2 ) * 100 / m_ZoomNext );
2897|    Sleep(250);
2898|  }
2899|
2900|  m_Zoom = zoom;
2901|  m_ZoomNext = zoom;
2902|  m_bBitmap = FALSE;
2903|  m_ZoomMode = CChildView_ZoomNormal;
2904|  SetScrollSize();
2905|  DrawBackBitmap();
2906|  Invalidate( FALSE );
2907|
2908|  ERRORS_FUNC_END_CPP( CChildView_Zoom );
2909|}
2910|
2911|void  CChildView::OnZoom()
2912|{
2913|  CSVGCatApp*   app = (CSVGCatApp*)AfxGetApp();
2914|
2915|  if ( m_InkOverlay != NULL ) {
2916|    CInputIntDlg  dlg;
2917|
2918|    dlg.m_Msg = app->m_bJapanese ? "拡大率" : "Zoom Rate";  dlg.m_Value = m_Zoom;
2919|    dlg.m_Min = 1;  dlg.m_Max = 10000;
2920|    if ( dlg.DoModal() == IDOK ) {
2921|      Zoom( dlg.m_Value );
2922|    }
2923|  }
2924|  else {
2925|    CInputIntDlg1  dlg;
2926|
2927|    dlg.m_Msg = app->m_bJapanese ? "拡大率" : "Zoom Rate";  dlg.m_Value = m_Zoom;
2928|    dlg.m_Min = 1;  dlg.m_Max = 10000;
2929|    if ( dlg.DoModal() == IDOK ) {
2930|      Zoom( dlg.m_Value );
2931|    }
2932|  }
2933|}
2934|
2935|void  CChildView::OnZoom100()
2936|{
2937|  Zoom( 100 );
2938|}
2939|
2940|void  CChildView::OnZoom200()
2941|{
2942|  Zoom( 200 );
2943|}
2944|
2945|void CChildView::OnZoom400()
2946|{
2947|  Zoom( 400 );
2948|}
2949|
2950|void CChildView::OnZoom800()
2951|{
2952|  Zoom( 800 );
2953|}
2954|
2955|void CChildView::OnZoomIn()
2956|{
2957|  int  z0 = 100;
2958|  int  z1;
2959|
2960|  if ( m_ZoomNext < 100 ) {
2961|    do {
2962|      z1 = z0 / 2;
2963|      if ( m_ZoomNext >= z1 )  { Zoom( z0 );  return; }
2964|      z0 = z1;
2965|    } while ( z0 > 1 );
2966|    Zoom( 2 );
2967|  }
2968|  else {
2969|    do {
2970|      z1 = z0 * 2;
2971|      if ( m_ZoomNext < z1 )  { Zoom( z1 );  return; }
2972|      z0 = z1;
2973|    } while ( z0 <= 3200 );
2974|    Zoom( 6400 );
2975|  }
2976|}
2977|
2978|void CChildView::OnZoomOut()
2979|{
2980|  int  z0 = 100;
2981|  int  z1;
2982|
2983|  if ( m_ZoomNext <= 100 ) {
2984|    do {
2985|      z1 = z0 / 2;
2986|      if ( m_ZoomNext > z1 )  { Zoom( z1 );  return; }
2987|      z0 = z1;
2988|    } while ( z0 > 2 );
2989|    Zoom( 1 );
2990|  }
2991|  else {
2992|    do {
2993|      z1 = z0 * 2;
2994|      if ( m_ZoomNext <= z1 )  { Zoom( z0 );  return; }
2995|      z0 = z1;
2996|    } while ( z0 <= 3200 );
2997|    Zoom( 3200 );
2998|  }
2999|}
3000|
3001|void CChildView::OnZoomWhole()
3002|{
3003|  m_ZoomMode = CChildView_ZoomWhole;
3004|  SetScrollSize();
3005|  ScrollToPosition( CPoint( 0, 0 ) );
3006|
3007|  m_bBitmap = false;
3008|  SetScrollSize();
3009|  DrawBackBitmap();
3010|  Invalidate( FALSE );
3011|
3012|  if ( m_bExistOutOfCanvas ) {
3013|    CSVGCatApp*   app = (CSVGCatApp*)AfxGetApp();
3014|    if ( app->m_bJapanese ) {
3015|      MessageBox( "キャンバスの外に図形が出ています。 中に戻すときは、"
3016|        "[ 編集 | 全て選択 ] を選び、カーソルキーで図形を移動させてください。",
3017|        "ヒント", MB_OK );
3018|    }
3019|    else {
3020|      MessageBox( "There are figures out of canvas. If you want to move it,"
3021|        "[ Edit | Select All ] and push cursor key.",
3022|        "Hint", MB_OK );
3023|    }
3024|  }
3025|}
3026|
3027|void CChildView::OnZoomWidth()
3028|{
3029|  m_ZoomMode = CChildView_ZoomWidth;
3030|  SetScrollSize();
3031|  m_bBitmap = false;
3032|  SetScrollSize();
3033|  DrawBackBitmap();
3034|  Invalidate( FALSE );
3035|}
3036|
3037|void CChildView::OnZoomSwap()
3038|{
3039|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
3040|  CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
3041|  int    nextZoom = m_ZoomSwitchZoom;
3042|  POINT  nextOffset = m_ZoomSwitchOffset;
3043|  int    nextMode = m_ZoomSwitchMode;
3044|  int    iPage = m_ZoomSwitchPage;
3045|  POINT  pt = GetScrollPosition();
3046|  RECT   rect;
3047|
3048|  m_ZoomSwitchZoom = m_Zoom;
3049|  m_ZoomSwitchOffset = pt;
3050|  m_ZoomSwitchMode = m_ZoomMode;
3051|  m_ZoomSwitchPage = app->m_file.m_CurrentPageNum;
3052|  m_bDisableSwapRec = false;
3053|
3054|  if ( iPage == 0 || m_ZoomSwitchPage == 0 )
3055|    frame->OnMakeBackPage();
3056|  else
3057|    frame->ChgPage( iPage );
3058|  m_Zoom = nextZoom;
3059|  m_ZoomMode = nextMode;
3060|  SetScrollSize();
3061|  GetClientRect( &rect );
3062|  ScrollToPosition( nextOffset );
3063|  m_bBitmap = false;
3064|  Invalidate( FALSE );
3065|}
3066|
3067|
3068| 
3069|/***********************************************************************
3070|  33. <<< [CChildView::SetZoomByCulc] ウィンドウに合わせてズームの値を計算する >>> 
3071|************************************************************************/
3072|void  CChildView::SetZoomByCulc()
3073|{
3074|  CSVGCatApp*   app = (CSVGCatApp*)AfxGetApp();
3075|  RECT  client;
3076|
3077|  switch ( m_ZoomMode ) {
3078|
3079|    case  CChildView_ZoomNormal:
3080|      m_bExistOutOfCanvas = false;
3081|      m_MinusOffset.x = 0;  m_MinusOffset.y = 0;
3082|      break;
3083|
3084|    case  CChildView_ZoomWhole: {
3085|      CadPrim*  target;
3086|      int       target_value;
3087|      CadPrim*  prim;
3088|      int       value;
3089|      RECT      whole;
3090|      int       zoom1, zoom2;
3091|      ListX_ElemX*  p;
3092|      bool  bPrevOutOfCanvas = m_bExistOutOfCanvas;
3093|
3094|      m_bExistOutOfCanvas = false;
3095|
3096|      /* キャンバスの全体または、その外にある図形を含めた全体の座標を whole に設定する */
3097|      if ( ListX_getFirst( &app->m_file.m_prims, ListX_ElemX ) == NULL ) {
3098|        whole.left = 0;
3099|        whole.top = 0;
3100|        whole.right = app->m_file.m_Canvas.m_Width;
3101|        whole.bottom = app->m_file.m_Canvas.m_Height;
3102|      }
3103|      else {
3104|        SetDrawnParam( &app->m_file.m_prims );
3105|        target = ((CadPrim*)ListX_getFirst( &app->m_file.m_prims, ListX_ElemX )->p);
3106|        target_value = target->GetForAlign( CadPrim_AlignLeft );
3107|        for ( ListX_forEach( &app->m_file.m_prims, &p, ListX_ElemX ) ) {
3108|          prim = (CadPrim*)p->p;
3109|          value = prim->GetForAlign( CadPrim_AlignLeft );
3110|          if ( value < target_value )
3111|            { target = prim;  target_value = value; }
3112|        }
3113|        whole.left = ( target_value < 0 ) ? target_value : 0;
3114|        m_bExistOutOfCanvas |= ( target_value < 0 );
3115|
3116|        target = ((CadPrim*)ListX_getFirst( &app->m_file.m_prims, ListX_ElemX )->p);
3117|        target_value = target->GetForAlign( CadPrim_AlignRight );
3118|        for ( ListX_forEach( &app->m_file.m_prims, &p, ListX_ElemX ) ) {
3119|          prim = (CadPrim*)p->p;
3120|          value = prim->GetForAlign( CadPrim_AlignRight );
3121|          if ( value > target_value )
3122|            { target = prim;  target_value = value; }
3123|        }
3124|        whole.right = ( target_value > app->m_file.m_Canvas.m_Width ) ?
3125|          target_value : app->m_file.m_Canvas.m_Width;
3126|        m_bExistOutOfCanvas |= ( target_value > app->m_file.m_Canvas.m_Width );
3127|
3128|        target = ((CadPrim*)ListX_getFirst( &app->m_file.m_prims, ListX_ElemX )->p);
3129|        target_value = target->GetForAlign( CadPrim_AlignTop );
3130|        for ( ListX_forEach( &app->m_file.m_prims, &p, ListX_ElemX ) ) {
3131|          prim = (CadPrim*)p->p;
3132|          value = prim->GetForAlign( CadPrim_AlignTop );
3133|          if ( value < target_value )
3134|            { target = prim;  target_value = value; }
3135|        }
3136|        whole.top = ( target_value < 0 ) ? target_value : 0;
3137|        m_bExistOutOfCanvas |= ( target_value < 0 );
3138|
3139|        target = ((CadPrim*)ListX_getFirst( &app->m_file.m_prims, ListX_ElemX )->p);
3140|        target_value = target->GetForAlign( CadPrim_AlignBottom );
3141|        for ( ListX_forEach( &app->m_file.m_prims, &p, ListX_ElemX ) ) {
3142|          prim = (CadPrim*)p->p;
3143|          value = prim->GetForAlign( CadPrim_AlignBottom );
3144|          if ( value > target_value )
3145|            { target = prim;  target_value = value; }
3146|        }
3147|        whole.bottom = ( target_value > app->m_file.m_Canvas.m_Height ) ?
3148|          target_value : app->m_file.m_Canvas.m_Height;
3149|        m_bExistOutOfCanvas |= ( target_value > app->m_file.m_Canvas.m_Height );
3150|      }
3151|
3152|      GetClientRect( &client );
3153|
3154|      zoom1 = ( client.right - 6 ) * 100 / ( whole.right - whole.left );
3155|      zoom2 = ( client.bottom - 6 ) * 100 / ( whole.bottom - whole.top );
3156|      m_Zoom = ( zoom1 < zoom2 ) ? zoom1 : zoom2;
3157|      if ( m_Zoom < 1 )  m_Zoom = 1;
3158|      m_MinusOffset.x = - whole.left;  m_MinusOffset.y = - whole.top;
3159|      m_bBitmap = false;
3160|      if ( bPrevOutOfCanvas && ! m_bExistOutOfCanvas ) {
3161|        m_bExistOutOfCanvas = true;  /* キャンバスでクリッピングしない */
3162|        Invalidate( FALSE );
3163|        m_bExistOutOfCanvas = false;
3164|      }
3165|      break;
3166|    }
3167|    case  CChildView_ZoomWidth:
3168|      GetClientRect( &client );
3169|      m_Zoom = ( client.right - 6 )* 100 / app->m_file.m_Canvas.m_Width;
3170|      if ( m_Zoom < 1 )  m_Zoom = 1;
3171|      m_MinusOffset.x = 0;  m_MinusOffset.y = 0;
3172|      m_bExistOutOfCanvas = false;
3173|      break;
3174|  }
3175|}
3176|
3177| 
3178|/***********************************************************************
3179|  34. <<< [CChildView::OnEraseBkgnd] ウィンドウをクリアする処理の横取り >>> 
3180|************************************************************************/
3181|BOOL CChildView::OnEraseBkgnd(CDC* pDC) /* WM_ERASEBKGND */
3182|{
3183|	return TRUE;
3184|//  return  CScrollView ::OnEraseBkgnd(pDC);
3185|   // これをコメントアウトしないと、CPaintDC のコンストラクタ
3186|   // (BeginPaint)で全体をクリアしてしまうので、ちらつきが出る。
3187|}
3188|
3189|
3190| 
3191|/***********************************************************************
3192|  35. <<< [CChildView::SetCursorSVGCats] マウスカーソルの形状を決定する >>> 
3193|************************************************************************/
3194|void  CChildView::SetCursorSVGCats( CPoint& point )
3195|{
3196|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
3197|  CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
3198|  int  iHandle, dx, dy, arrow;
3199|  CadPrim*  prim;
3200|
3201|  WaitForSingleObject( app->m_FileSema, INFINITE );
3202|
3203|
3204|  if ( point.x > app->m_file.m_Canvas.m_Width || point.y > app->m_file.m_Canvas.m_Height ) {
3205|
3206|    /* キャンバスのサイズを変更するハンドルの上のとき */
3207|    if ( point.x >= app->m_file.m_Canvas.m_Width - 4 * 100 / (m_Zoom>100 ? 100:m_Zoom) &&
3208|         point.x <= app->m_file.m_Canvas.m_Width + 8 * 100 / (m_Zoom>100 ? 100:m_Zoom) &&
3209|         point.y >= app->m_file.m_Canvas.m_Height - 4 * 100 / (m_Zoom>100 ? 100:m_Zoom) &&
3210|         point.y <= app->m_file.m_Canvas.m_Height + 8 * 100 / (m_Zoom>100 ? 100:m_Zoom) )
3211|      { m_Cursor = LoadCursor( NULL, IDC_SIZENWSE );  goto ret; }
3212|
3213|    /* キャンバスの外のとき */
3214|    else
3215|      { m_Cursor = LoadCursor( NULL, IDC_ARROW );  goto ret; }
3216|  }
3217|
3218|  /* インクのサイズを変更するハンドルの上のとき */
3219|  if ( point.x >= m_InkResizeHandlePos.x - 4 &&  point.x <= m_InkResizeHandlePos.x + 4 &&
3220|       point.y >= m_InkResizeHandlePos.y - 4 &&  point.y <= m_InkResizeHandlePos.y + 4 )
3221|    { m_Cursor = LoadCursor( NULL, IDC_SIZENWSE );  goto ret; }
3222|
3223|
3224|  /* 何も無いキャンバスの上でのカーソルの形状を決定する */
3225|  switch ( frame->m_mode ) {
3226|    case  CMainFrame_CreateLine:
3227|      m_Cursor = app->LoadCursor( IDC_CursorForLine );  break;
3228|    case  CMainFrame_CreateArrow:
3229|      m_Cursor = app->LoadCursor( IDC_CursorForArrow );  break;
3230|    case  CMainFrame_CreateLineCorner:
3231|      m_Cursor = app->LoadCursor( IDC_CursorForLineCorner );  break;
3232|    case  CMainFrame_CreateGuideLine:
3233|      m_Cursor = app->LoadCursor( IDC_CursorForGuideLine );  break;
3234|    case  CMainFrame_CreateMatome:
3235|      m_Cursor = app->LoadCursor( IDC_CursorForMatome );  break;
3236|    case  CMainFrame_CreateRect:
3237|      m_Cursor = app->LoadCursor( IDC_CursorForRect );  break;
3238|    case  CMainFrame_CreateCircle:
3239|      m_Cursor = app->LoadCursor( IDC_CursorForCircle );  break;
3240|    case  CMainFrame_CreateTransCircle:
3241|      m_Cursor = app->LoadCursor( IDC_CursorForTransCircle );  break;
3242|    case  CMainFrame_CreateRoundRect:
3243|      m_Cursor = app->LoadCursor( IDC_CursorForRoundRect );  break;
3244|    case  CMainFrame_CreateDiamond:
3245|      m_Cursor = app->LoadCursor( IDC_CursorForDiamond );  break;
3246|    case  CMainFrame_CreateImage:
3247|      m_Cursor = app->LoadCursor( IDC_CursorForImage );  break;
3248|    case  CMainFrame_CreateText:
3249|      m_Cursor = app->LoadCursor( IDC_CursorForText );  break;
3250|    case  CMainFrame_CreateRedText:
3251|      m_Cursor = app->LoadCursor( IDC_CursorForRedText );  break;
3252|    case  CMainFrame_CreateBlueText:
3253|      m_Cursor = app->LoadCursor( IDC_CursorForBlueText );  break;
3254|    case  CMainFrame_CreateTimeStamp:
3255|      m_Cursor = app->LoadCursor( IDC_CursorForTimeStamp );  break;
3256|    case  CMainFrame_CreateTextBox:
3257|      m_Cursor = app->LoadCursor( IDC_CursorForTextBox );  break;
3258|    case  CMainFrame_CreateTextCircle:
3259|      m_Cursor = app->LoadCursor( IDC_CursorForTextCircle );  break;
3260|    case  CMainFrame_CreateTextRound:
3261|      m_Cursor = app->LoadCursor( IDC_CursorForTextRound );  break;
3262|    case  CMainFrame_CreateTextDiamond:
3263|      m_Cursor = app->LoadCursor( IDC_CursorForTextDiamond );  break;
3264|    case  CMainFrame_CreateTextParal:
3265|      m_Cursor = app->LoadCursor( IDC_CursorForTextParal );  break;
3266|    case  CMainFrame_UseInk:
3267|      m_Cursor = app->LoadCursor( IDC_UseInk );  break;
3268|    case  CMainFrame_Rotate:
3269|      m_Cursor = app->LoadCursor( IDC_CursorForRotateArrow );  break;
3270|    case  CMainFrame_Zooming:
3271|      m_Cursor = LoadCursor( NULL, IDC_ARROW );  goto ret;
3272|    default:
3273|      m_Cursor = LoadCursor( NULL, IDC_ARROW );  break;
3274|  }
3275|
3276|  /* 選択中のインクの上のときのカーソル */
3277|  if ( IsHitSelectedInk( point.x, point.y ) )
3278|    m_Cursor = app->LoadCursor( IDC_CursorMovable );
3279|
3280|
3281|  /* 図形の上やハンドルの上のカーソルを決定する */
3282|  if ( ( ! m_bFirstCreate && ! frame->m_bStrongCreate ) || frame->m_mode == CMainFrame_Rotate ) {
3283|
3284|    c_try {
3285|      prim = app->GetNearestHandle( point.x, point.y, m_Zoom, frame->GetCadPrimMode(),
3286|        &iHandle, &dx, &dy, &arrow, m_HoldPrim );
3287|    }
3288|    c_catch ( Errors_Msg*, msg ) {
3289|      if ( msg->code != SVGCat_Err_NotSetDrawParam )  c_throw_again();
3290|      arrow = CadPrim_NormalArrow;
3291|    } c_end_catch;
3292|
3293|    switch ( arrow ) {
3294|      case  CadPrim_NormalArrow:     break;  /* 上で設定したものを使う */
3295|      case  CadPrim_MovableArrow:
3296|        if ( frame->m_mode == CMainFrame_Rotate )
3297|          { m_Cursor = app->LoadCursor( IDC_CursorForRotate );  break; }
3298|        else
3299|          { m_Cursor = app->LoadCursor( IDC_CursorMovable );  break; }
3300|      case  CadPrim_HorizontalArrow: m_Cursor = LoadCursor( NULL, IDC_SIZEWE );  break;
3301|      case  CadPrim_VerticalArrow:   m_Cursor = LoadCursor( NULL, IDC_SIZENS );  break;
3302|      case  CadPrim_RightDownArrow:  m_Cursor = LoadCursor( NULL, IDC_SIZENWSE );  break;
3303|      case  CadPrim_RightUpArrow:    m_Cursor = LoadCursor( NULL, IDC_SIZENESW );  break;
3304|      case  CadPrim_CrossArrow:      m_Cursor = LoadCursor( NULL, IDC_SIZEALL );  break;
3305|      case  CadPrim_NoArrow:         m_Cursor = LoadCursor( NULL, IDC_NO );  break;
3306|    }
3307|
3308|    /* 複数選択のときは、図形の上ではどこでも移動可能カーソルにする */
3309|    if ( arrow != CadPrim_NormalArrow && ListX_getN( &m_MultiHolds, ListX_ElemX ) >= 2 )
3310|      m_Cursor = app->LoadCursor( IDC_CursorMovable );
3311|  }
3312|
3313|
3314|  /* テキスト編集モードでカーソルを消す */
3315|  if ( m_bEditorEnable ) {
3316|    if ( abs( m_DownS.x - point.x ) > 8 || abs( m_DownS.y - point.y ) > 8 )
3317|      m_DownS.x = INT_MAX;
3318|    else
3319|      m_Cursor = NULL;
3320|  }
3321|
3322|ret:
3323|  ReleaseSemaphore( app->m_FileSema, 1, NULL );
3324|}
3325|
3326|
3327|BOOL CChildView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
3328|{
3329|  CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
3330|
3331|  if ( frame->m_bActivated ) {
3332|    switch ( nHitTest ) {
3333|      case HTCLIENT:  SetCursor( m_Cursor );  break;
3334|      default:  SetCursor( LoadCursor( NULL, IDC_ARROW ) );  break;
3335|    }
3336|  }
3337|  else
3338|    SetCursor( LoadCursor( NULL, IDC_ARROW ) );
3339|
3340|  return  TRUE; // CScrollView ::OnSetCursor(pWnd, nHitTest, message);
3341|}
3342|
3343| 
3344|/***********************************************************************
3345|  36. <<< [CChildView::OnLButtonDown] クリックしたときの処理 >>> 
3346|************************************************************************/
3347|void CChildView::OnLButtonDown(UINT nFlags, CPoint point)
3348|{
3349|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
3350|  CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
3351|
3352|  frame->m_bScopeHidingCancel = true;
3353|
3354|  if ( frame->m_bMouseActivated ) {
3355|    frame->m_bActivated = true;
3356|    frame->m_bMouseActivated = false;
3357|    return;
3358|  }
3359|
3360|  if ( frame->IsPenMode() ) {
3361|    if ( point.x > app->m_file.m_Canvas.m_Width * m_Zoom / 100 ||
3362|         point.y > app->m_file.m_Canvas.m_Height * m_Zoom / 100 ) {
3363|      ;  /* キャンバスサイズ変更のため return しない */
3364|    }
3365|    else {
3366|      static int  prevTime = -1200;
3367|
3368|      if ( GetTickCount() - prevTime > 1200 )  // あまり効果なかったかも
3369|        ResetSelect( false );
3370|      prevTime = GetTickCount();
3371|      return;
3372|    }
3373|  }
3374|
3375|  bool  bShift = ( nFlags & MK_SHIFT ) != 0;
3376|  bool  bCtrl = ( nFlags & MK_CONTROL ) != 0;
3377|  CadPrim*  prim;
3378|  CClientDC  dc( this );
3379|  int  iHandle;
3380|  int  arrow;
3381|  int  mode;
3382|  POINT  pt;
3383|  ERRORS_FUNC_CPP_VAR( CChildView_OnLButtonDown );
3384|  ERRORS_FUNC_START_CPP( CChildView_OnLButtonDown );
3385|
3386|  if ( m_SingleDblClickTimer != 0 )  frame->KillTimer( m_SingleDblClickTimer );
3387|  m_SingleDblClickTimer = 0;
3388|
3389|  if ( m_bRightDrag ) {
3390|    m_bRightDrag = false;
3391|    m_bRightMenuAble = false;
3392|    ResetSelect();
3393|    if ( m_PrevCanvasHeight != -1 )
3394|      { m_PrevCanvasHeight = -1;  Redraw(FALSE); }
3395|    SetCursorSVGCats( point );
3396|    SetCursor( m_Cursor );
3397|
3398|    OnEditUndo();
3399|
3400|    ERRORS_FUNC_END_CPP( CChildView_OnLButtonDown );
3401|    return;
3402|  }
3403|
3404|  { /* ずれてダブルクリックしたときも有効にする */
3405|    static int  t = 0;
3406|
3407|    if ( GetTickCount() - t < GetDoubleClickTime() ) {
3408|      OnLButtonDblClk( nFlags, point );
3409|      t = GetTickCount();
3410|      ERRORS_FUNC_END_CPP( CChildView_OnLButtonDown );
3411|      return;
3412|    }
3413|    t = GetTickCount();
3414|  }
3415|
3416|  pt = GetScrollPosition();
3417|  point += pt;
3418|  point -= m_MinusOffset;
3419|  point.x = point.x * 100 / m_Zoom;
3420|  point.y = point.y * 100 / m_Zoom;
3421|  m_DownS = point;
3422|
3423|  SetCapture();
3424|  m_DragPrim = NULL;
3425|  m_bSelectedClick = FALSE;
3426|  m_bInDragPlay = TRUE;
3427|  m_bUnholdable = false;
3428|
3429|  #ifdef  USES_INK
3430|  if ( frame->IsPenMode() ) {
3431|    Ink_Line*  line;
3432|    CadPrim_DrawParam  pa;
3433|
3434|    GetDrawParam( &pa );
3435|
3436|    line = new Ink_Line;
3437|    line->m_id = app->GetNewPrimID();
3438|    line->m_bHold = false;
3439|    line->ScratchStart( &dc, &pa, point.x, point.y );
3440|    app->AddPrim( line );
3441|
3442|    m_HoldInk = line;
3443|    m_bCreate = TRUE;
3444|    m_bDrag = TRUE;
3445|    m_iHoldHandle = 0;
3446|    ERRORS_FUNC_END_CPP( CChildView_OnLButtonDown );
3447|    return;
3448|  }
3449|  #endif
3450|
3451|
3452|  /* カーソルキーによる移動(CadPrim::Move)での操作をアンドゥバッファへ記録する */
3453|  OnFinishPrimMove();
3454|
3455|  /* 選択状態の整合性チェック */
3456|  #ifndef  NDEBUG
3457|  {
3458|    ListX_ElemX*  p;
3459|    ListX_ElemX*  p2;
3460|    CadPrim*  prim;
3461|
3462|    //app->printPrims(&app->m_file.m_prims,"");
3463|
3464|    for ( ListX_forEach( &app->m_file.m_prims, &p, ListX_ElemX ) ) {
3465|      for ( ListX_forEach( &m_MultiHolds, &p2, ListX_ElemX ) ) {
3466|        if ( p2->p == p->p )  break;
3467|      }
3468|      prim = (CadPrim*)p->p;
3469|      if ( ( p2 != NULL || m_HoldPrim == prim ) && ! prim->GetHold() ) {
3470|        Errors_printf( "not selected error, ID=%d, p2=%p, m_HoldPrim=%p, prim=%p",
3471|          prim->GetID(), p2, m_HoldPrim, prim );
3472|        error();
3473|      }
3474|      if ( p2 == NULL && m_HoldPrim != prim && prim->GetHold() ) {
3475|        Errors_printf( "selected error, ID=%d, p2=%p, m_HoldPrim=%p, prim=%p",
3476|          prim->GetID(), p2, m_HoldPrim, prim );
3477|        error();
3478|      }
3479|    }
3480|    //Errors_X3 = (int)Undo_Uty_getPrimPtr( &app->m_file.m_prims, 2 );
3481|  }
3482|  #endif
3483|
3484|
3485|  /* キャンバスの外のときは、選択を解除する */
3486|  if ( point.x > app->m_file.m_Canvas.m_Width || point.y > app->m_file.m_Canvas.m_Height ) {
3487|    ResetSelect();
3488|
3489|    /* キャンバスのハンドルにヒットしたとき */
3490|    if ( point.x >= app->m_file.m_Canvas.m_Width - 4 * 100 / (m_Zoom>100 ? 100:m_Zoom) &&
3491|         point.x <= app->m_file.m_Canvas.m_Width + 8 * 100 / (m_Zoom>100 ? 100:m_Zoom) &&
3492|         point.y >= app->m_file.m_Canvas.m_Height - 4 * 100 / (m_Zoom>100 ? 100:m_Zoom) &&
3493|         point.y <= app->m_file.m_Canvas.m_Height + 8 * 100 / (m_Zoom>100 ? 100:m_Zoom) ) {
3494|      m_DownX = point.x;  m_DownY = point.y;
3495|      pt = GetScrollPosition();
3496|      m_iHoldHandle = 1;
3497|      m_HoldPrim = &app->m_file.m_Canvas;
3498|      m_BeforePrim = app->m_file.m_Canvas.GetNewCopy( &app->m_file.m_prims );
3499|      m_bDrag = TRUE;
3500|      m_bInDragPlay = TRUE;
3501|    }
3502|    Redraw( false );
3503|    frame->ResetProp();
3504|
3505|    ERRORS_FUNC_END_CPP( CChildView_OnLButtonDown );
3506|    return;
3507|  }
3508|
3509|  /* 各モードごとにクリックした直後の反応をする */
3510|  prim = app->GetNearestHandle( point.x, point.y, m_Zoom,
3511|    frame->GetCadPrimMode(), &iHandle, &m_Hold_dx, &m_Hold_dy, &arrow, m_HoldPrim );
3512|  if ( ! m_bFirstCreate && ! frame->m_bStrongCreate && prim != NULL &&
3513|       iHandle != 0 && frame->m_mode != CMainFrame_Rotate &&
3514|       frame->m_mode != CMainFrame_Zooming && frame->m_mode != CMainFrame_SelectMulti ) {
3515|    mode = CMainFrame_Select;
3516|  }
3517|  else
3518|    mode = frame->m_mode;
3519|
3520|  m_bHitInk = IsHitSelectedInk( point.x, point.y );
3521|
3522|
3523|  switch ( mode ) {
3524|
3525|   case CMainFrame_Select:
3526|   case CMainFrame_SelectMulti:
3527|
3528|    m_bEditorEnable = false;
3529|
3530|
3531|    /* インクのリサイズ・ハンドルにヒットしたとき */
3532|    if ( m_HoldStrokes != NULL &&
3533|         point.x >= m_InkResizeHandlePos.x - 4 && point.x <= m_InkResizeHandlePos.x + 4 &&
3534|         point.y >= m_InkResizeHandlePos.y - 4 && point.y <= m_InkResizeHandlePos.y + 4  ) {
3535|      IInkStrokes*  strokes;
3536|
3537|      m_iHoldHandle = -3;
3538|      m_Hold_dx = point.x - m_InkResizeHandlePos.x;
3539|      m_Hold_dy = point.y - m_InkResizeHandlePos.y;
3540|      strokes = DuplicateStrokes( m_HoldStrokes );
3541|      ResetSelect( false );  /* 図形の選択を解除する */
3542|      m_HoldStrokes = strokes;
3543|      SyncHoldStrokes();
3544|      frame->SetDefaultMode();
3545|    }
3546|    else if ( prim == NULL && ! m_bHitInk ) {
3547|
3548|      /* どの図形にもヒットしなかったとき */
3549|      if ( ! bCtrl && ! bShift ) {
3550|        ListX_ElemX*  p;
3551|
3552|        ListX_toEmptyDelete( &m_MultiHolds, ListX_ElemX, NULL );
3553|        for ( ListX_forEach( &app->m_file.m_prims, &p, ListX_ElemX ) )
3554|          ((CadPrim*)p->p)->SetHold( false );
3555|        for ( ListX_forEach( &m_MultiBefore, &p, ListX_ElemX) )
3556|          delete  (CadPrim*)p->p;
3557|        ListX_toEmptyDelete( &m_MultiBefore, ListX_ElemX, NULL );
3558|        if ( m_HoldStrokes != NULL )  { m_HoldStrokes->Release();  m_HoldStrokes = NULL; }
3559|      }
3560|      /* キャンバスのハンドルにヒットしたとき */
3561|      if ( point.x >= app->m_file.m_Canvas.m_Width - 4 &&
3562|           point.x <= app->m_file.m_Canvas.m_Width + 8 &&
3563|           point.y >= app->m_file.m_Canvas.m_Height - 4 &&
3564|           point.y <= app->m_file.m_Canvas.m_Height + 8 ) {
3565|        m_Hold_dx = 0;  m_Hold_dy = 0;
3566|        m_iHoldHandle = 1;
3567|        m_HoldPrim = &app->m_file.m_Canvas;
3568|        m_BeforePrim = app->m_file.m_Canvas.GetNewCopy( &app->m_file.m_prims );
3569|      }
3570|      else {
3571|        m_bInDragPlay = TRUE;
3572|        m_HoldPrim = NULL;
3573|        m_iHoldHandle = 2;
3574|      }
3575|
3576|      frame->ResetProp();
3577|    }
3578|
3579|    else {
3580|      ListX_ElemX*  p;
3581|      ListX_ElemX*  p2;
3582|
3583|      /* インクのみ選択中のときにインクにヒットしたとき */
3584|      if ( m_bHitInk ) {
3585|        m_iHoldHandle = -2;
3586|      }
3587|
3588|      /* prim にヒットしたとき */
3589|      else {
3590|        for ( ListX_forEach( &m_MultiHolds, &p, ListX_ElemX ) ) {
3591|          if ( p->p == prim )  break;
3592|        }
3593|
3594|        /* Ctrl キーを押しながらヒットしたら、選択状態を切り替える */
3595|        if ( bCtrl || bShift || ( mode == CMainFrame_SelectMulti /*&&
3596|             ( ListX_getN( &m_MultiHolds, ListX_ElemX ) > 1 || prim != m_HoldPrim )*/ ) ) {
3597|          if ( ! prim->IsHoldable() )
3598|            break;
3599|          if ( p == NULL ) {
3600|            p = ListX_addLastMalloc( &m_MultiHolds, ListX_ElemX );
3601|            p->p = prim;
3602|            m_HoldPrim = prim;
3603|            m_DragPrim = prim;
3604|            m_iHoldHandle = -2;
3605|            prim->SetHold( true );
3606|            frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
3607|          }
3608|          else {
3609|            /* 代表を変える */
3610|            ListX_remove( &m_MultiHolds, p );
3611|            ListX_addFirst( &m_MultiHolds, p );
3612|            m_bSelectedClick = TRUE;
3613|            m_HoldPrim = prim;
3614|            m_DragPrim = prim;
3615|            m_iHoldHandle = -2;
3616|            m_bUnholdable = true;
3617|          }
3618|        }
3619|
3620|        /* Ctrl キーが押されていなかったら、1つを選択するか、基準を切り替える */
3621|        else {
3622|
3623|          if ( p == NULL ) {  /* 選択状態でないものをクリックしたとき */
3624|            ListX_toEmptyDelete( &m_MultiHolds, ListX_ElemX, NULL );
3625|            for ( ListX_forEach( &app->m_file.m_prims, &p, ListX_ElemX ) )
3626|              ((CadPrim*)p->p)->SetHold( false );
3627|            p = ListX_addLastMalloc( &m_MultiHolds, ListX_ElemX );
3628|            p->p = prim;
3629|            if ( m_HoldStrokes != NULL )  { m_HoldStrokes->Release();  m_HoldStrokes = NULL; }
3630|          }
3631|          else {  /* 選択状態ものものをクリックしたとき */
3632|            ListX_remove( &m_MultiHolds, p );
3633|            ListX_addFirst( &m_MultiHolds, p );
3634|            m_bSelectedClick = TRUE;
3635|
3636|            #ifdef  SvgCats_DirectInput
3637|            if ( prim->GetTypeID() == Text_Box_TypeID ) {
3638|              m_Editor->Attach( (Text_Box*)prim );
3639|              m_bEditorEnable = true;
3640|            }
3641|            #endif
3642|          }
3643|          m_HoldPrim = prim;
3644|          m_DragPrim = prim;
3645|          m_iHoldHandle = iHandle;
3646|          if ( m_iHoldHandle != 0 && ListX_getN( &m_MultiHolds, ListX_ElemX ) > 1 )
3647|            m_iHoldHandle = -2;
3648|          frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
3649|        }
3650|        if ( mode != CMainFrame_SelectMulti )  frame->SetDefaultMode();
3651|      }
3652|
3653|      /* 選択状態の調節 */
3654|      for ( ListX_forEach( &m_MultiHolds, &p, ListX_ElemX ) ) {
3655|        ((CadPrim*)p->p)->SetHold( true );
3656|      }
3657|      SetMultiSelect();
3658|
3659|      /* アンドゥバッファに記録する対象を設定する */
3660|      if ( m_BeforePrim != NULL )  delete  m_BeforePrim;
3661|      for ( ListX_forEach( &m_MultiHolds, &p, ListX_ElemX ) ) {
3662|        if ( (CadPrim*)p->p == prim )  break;
3663|      }
3664|      if ( p == NULL ) {
3665|        p = ListX_getFirst( &m_MultiHolds, ListX_ElemX );
3666|      }
3667|      m_BeforePrim = ( p == NULL ? NULL: ((CadPrim*)p->p)->GetNewCopy( &app->m_file.m_prims ) );
3668|      if ( m_BeforePrim != NULL )  m_BeforePrim->SetBInUndoBuf( true );
3669|
3670|      ListX_toEmptyDelete( &m_MultiBefore, ListX_ElemX, NULL );
3671|      ASSERT( ListX_getN( &m_MultiBefore, ListX_ElemX ) == 0 );
3672|      for ( ListX_forEach( &m_MultiSelects, &p, ListX_ElemX ) ) {
3673|        p2 = ListX_addLastMalloc( &m_MultiBefore, ListX_ElemX );
3674|        p2->p = ((CadPrim*)p->p)->GetNewCopy( &app->m_file.m_prims );
3675|        ((CadPrim*)p2->p)->SetBInUndoBuf( true );
3676|      }
3677|    }
3678|
3679|    m_DownX = point.x;  m_DownY = point.y;
3680|    if ( m_iHoldHandle > 0 ) {
3681|      m_Hold_dx = 0;  m_Hold_dy = 0;
3682|    }
3683|    m_bDrag = TRUE;
3684|    m_bInDragPlay = TRUE;
3685|    Redraw( false );
3686|    break;
3687|
3688|
3689|   case CMainFrame_Rotate: {
3690|    ListX_ElemX*  p;
3691|
3692|    m_HoldPrim = NULL;
3693|    ListX_toEmptyDelete( &m_MultiHolds, ListX_ElemX, NULL );
3694|    for ( ListX_forEach( &app->m_file.m_prims, &p, ListX_ElemX ) )
3695|      ((CadPrim*)p->p)->SetHold( false );
3696|
3697|    if ( m_BeforePrim != NULL )  delete  m_BeforePrim;
3698|    for ( ListX_forEach( &m_MultiBefore, &p, ListX_ElemX) )
3699|      delete  (CadPrim*)p->p;
3700|    ListX_toEmptyDelete( &m_MultiBefore, ListX_ElemX, NULL );
3701|    if ( m_HoldStrokes != NULL )  { m_HoldStrokes->Release();  m_HoldStrokes = NULL; }
3702|
3703|
3704|    /* どの図形にもヒットしなかったとき */
3705|    if ( prim == NULL ) {
3706|      m_HoldPrim = NULL;
3707|      SetMultiSelect();
3708|      frame->ResetProp();
3709|    }
3710|
3711|    /* prim にヒットしたとき */
3712|    else {
3713|      ListX_ElemX*  p;
3714|
3715|      m_HoldPrim = prim;
3716|      if ( iHandle > 0 ) {
3717|        m_DragPrim = prim;
3718|      }
3719|      m_iHoldHandle = iHandle;
3720|
3721|      p = ListX_addLastMalloc( &m_MultiHolds, ListX_ElemX );
3722|      p->p = prim;
3723|      prim->SetHold( true );
3724|      SetMultiSelect();
3725|
3726|      m_BeforePrim = prim->GetNewCopy( &app->m_file.m_prims );
3727|      m_BeforePrim->SetBInUndoBuf( true );
3728|      p = ListX_addFirstMalloc( &m_MultiBefore, ListX_ElemX );
3729|      p->p = prim->GetNewCopy( &app->m_file.m_prims );
3730|      ((CadPrim*)p->p)->SetBInUndoBuf( true );
3731|
3732|      m_DownX = point.x;  m_DownY = point.y;
3733|      m_bDrag = ( iHandle > 0 );
3734|      m_bInDragPlay = m_bDrag;
3735|      frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
3736|    }
3737|
3738|    Redraw( false );
3739|    break;
3740|   }
3741|
3742|   case CMainFrame_CreateText:
3743|   case CMainFrame_CreateRedText:
3744|   case CMainFrame_CreateBlueText:
3745|   case CMainFrame_CreateTimeStamp:
3746|   case CMainFrame_CreateTextBox:
3747|   case CMainFrame_CreateTextRound:
3748|   case CMainFrame_CreateTextCircle:
3749|   case CMainFrame_CreateTextDiamond:
3750|   case CMainFrame_CreateTextParal: {
3751|
3752|    Text_Box*  text;
3753|    ListX_ElemX*  p;
3754|
3755|    app->m_file.m_Canvas.ChgToGridedPos( (int*)&point.x, (int*)&point.y );
3756|    point.y -= Text_Box_GridGap;
3757|    AutoAdjustXY( &point.x, &point.y, true, false );
3758|
3759|    for ( ListX_forEach( &m_MultiHolds, &p, ListX_ElemX ) )
3760|      ((CadPrim*)p->p)->SetHold( false );
3761|    ListX_toEmptyDelete( &m_MultiHolds, ListX_ElemX, NULL );
3762|    for ( ListX_forEach( &m_MultiBefore, &p, ListX_ElemX) )
3763|      delete  (CadPrim*)p->p;
3764|    ListX_toEmptyDelete( &m_MultiBefore, ListX_ElemX, NULL );
3765|    if ( m_HoldStrokes != NULL )  { m_HoldStrokes->Release();  m_HoldStrokes = NULL; }
3766|
3767|    text = NULL;
3768|    switch ( mode ) {
3769|     case CMainFrame_CreateText:
3770|       if ( frame->m_TextDesign != NULL )
3771|         text = (Text_Box*)frame->m_TextDesign->GetNewCopy( &app->m_file.m_prims );
3772|       break;
3773|     case CMainFrame_CreateRedText:
3774|       if ( frame->m_RedTextDesign != NULL )
3775|         text = (Text_Box*)frame->m_RedTextDesign->GetNewCopy( &app->m_file.m_prims );
3776|       break;
3777|     case CMainFrame_CreateBlueText:
3778|       if ( frame->m_BlueTextDesign != NULL )
3779|         text = (Text_Box*)frame->m_BlueTextDesign->GetNewCopy( &app->m_file.m_prims );
3780|       break;
3781|     case CMainFrame_CreateTimeStamp:
3782|       if ( frame->m_TimeStampDesign != NULL ) {
3783|         text = (Text_Box*)frame->m_TimeStampDesign->GetNewCopy( &app->m_file.m_prims );
3784|         text->m_Text = TimeDate_getNowStrF( text->m_Text );
3785|       }
3786|       break;
3787|     case CMainFrame_CreateTextBox:
3788|       if ( frame->m_TextRectDesign != NULL )
3789|         text = (Text_Box*)frame->m_TextRectDesign->GetNewCopy( &app->m_file.m_prims );
3790|       break;
3791|     case CMainFrame_CreateTextRound:
3792|       if ( frame->m_TextRoundRectDesign != NULL )
3793|         text = (Text_Box*)frame->m_TextRoundRectDesign->GetNewCopy( &app->m_file.m_prims );
3794|       break;
3795|     case CMainFrame_CreateTextCircle:
3796|       if ( frame->m_TextCircleDesign != NULL )
3797|         text = (Text_Box*)frame->m_TextCircleDesign->GetNewCopy( &app->m_file.m_prims );
3798|       break;
3799|     case CMainFrame_CreateTextDiamond:
3800|       if ( frame->m_TextDiamondDesign != NULL )
3801|         text = (Text_Box*)frame->m_TextDiamondDesign->GetNewCopy( &app->m_file.m_prims );
3802|       break;
3803|     case CMainFrame_CreateTextParal:
3804|       if ( frame->m_TextParallelDesign != NULL )
3805|         text = (Text_Box*)frame->m_TextParallelDesign->GetNewCopy( &app->m_file.m_prims );
3806|       break;
3807|    }
3808|    if ( text != NULL ) {
3809|      CadPrim_DrawParam  pa;
3810|
3811|      text->m_id = app->GetNewPrimID();
3812|      text->m_IdLabel = "";
3813|      text->m_bHold = true;
3814|      GetDrawParam( &pa );
3815|      text->Draw( &m_MinBitmapDC, &pa );  /* マージンを設定する */
3816|      text->m_CenterX = point.x;  text->m_Y = point.y;
3817|    }
3818|    else {
3819|      text = new Text_Box;
3820|      text->m_id = app->GetNewPrimID();
3821|      text->m_bHold = true;
3822|      text->m_Text = "ABC";
3823|      text->m_CenterX = point.x;  text->m_Y = point.y;
3824|      text->m_W = 100;  text->m_10H = 320;
3825|      text->m_Color = 0;
3826|      if ( mode == CMainFrame_CreateRedText )  text->m_Color = RGB(0xFF,0,0);
3827|      if ( mode == CMainFrame_CreateBlueText )  text->m_Color = RGB(0,0,0xFF);
3828|      if ( mode == CMainFrame_CreateTimeStamp ) {
3829|        text->m_Color = RGB(0xFF,0,0);
3830|        text->m_Text = TimeDate_getNowStrF( app->m_TimeStampFormat );
3831|      }
3832|      text->m_Font = _DefaultFont;
3833|      text->m_Size = 10;
3834|      text->m_bBold = ( mode == CMainFrame_CreateRedText ||
3835|                        mode == CMainFrame_CreateBlueText ||
3836|                        mode == CMainFrame_CreateTimeStamp );
3837|      text->m_bItalic = false;
3838|      switch ( mode ) {
3839|        case  CMainFrame_CreateText:
3840|        case  CMainFrame_CreateRedText:
3841|        case  CMainFrame_CreateBlueText:
3842|        case  CMainFrame_CreateTimeStamp:
3843|          text->m_BasePos = Text_Box_LeftAlign;
3844|          text->m_BoxShape = Text_Box_NoFrame;
3845|          text->m_BoxMarginX = 2;  text->m_BoxMarginY = 2;
3846|          break;
3847|        case  CMainFrame_CreateTextBox:
3848|          text->m_BasePos = Text_Box_CenterAlign;
3849|          text->m_BoxShape = Text_Box_RectShape;
3850|          text->m_BoxMarginX = 8;  text->m_BoxMarginY = 6;
3851|          break;
3852|        case  CMainFrame_CreateTextRound:
3853|          text->m_BasePos = Text_Box_CenterAlign;
3854|          text->m_BoxShape = Text_Box_RoundRectShape;
3855|          text->m_BoxMarginX = 8;  text->m_BoxMarginY = 6;
3856|          break;
3857|        case  CMainFrame_CreateTextCircle:
3858|          text->m_BasePos = Text_Box_CenterAlign;
3859|          text->m_BoxShape = Text_Box_CircleShape;
3860|          text->m_BoxMarginX = 10;  text->m_BoxMarginY = 8;
3861|          break;
3862|        case  CMainFrame_CreateTextDiamond:
3863|          text->m_BasePos = Text_Box_CenterAlign;
3864|          text->m_BoxShape = Text_Box_DiamondShape;
3865|          text->m_BoxMarginX = 28;  text->m_BoxMarginY = 8;
3866|          break;
3867|        case  CMainFrame_CreateTextParal:
3868|          text->m_BasePos = Text_Box_CenterAlign;
3869|          text->m_BoxShape = Text_Box_Parallelogram;
3870|          text->m_BoxMarginX = 10;  text->m_BoxMarginY = 6;
3871|          break;
3872|      }
3873|      text->m_BorderWidth = 1;
3874|      text->m_BorderColor = 0x000000;
3875|      text->m_FillColor = 0xFFFFFF;
3876|    }
3877|    app->AddPrim( &app->m_file, text );
3878|
3879|    Redraw( false );
3880|
3881|    m_HoldPrim = text;
3882|    m_DragPrim = text;
3883|    m_iHoldHandle = -1;
3884|    ListX_toEmptyDelete( &m_MultiHolds, ListX_ElemX, NULL );
3885|    p = ListX_addLastMalloc( &m_MultiHolds, ListX_ElemX );
3886|    p->p = m_HoldPrim;
3887|    SetMultiSelect();
3888|    m_Hold_dx = 0;  m_Hold_dy = 0;
3889|    m_DownX = -9999;  m_DownY = -9999;
3890|    m_bCreate = TRUE;
3891|    m_bDrag = TRUE;
3892|    m_bInDragPlay = TRUE;
3893|    frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
3894|    break;
3895|   }
3896|
3897|   case CMainFrame_CreateLine:
3898|   case CMainFrame_CreateArrow:
3899|   case CMainFrame_CreateGuideLine: {
3900|
3901|    Line_Ex*  line;
3902|    ListX_ElemX*  p;
3903|
3904|    app->m_file.m_Canvas.ChgToGridedPos( (int*)&point.x, (int*)&point.y );
3905|    AutoAdjustXY( &point.x, &point.y, true, false );
3906|
3907|    for ( ListX_forEach( &m_MultiHolds, &p, ListX_ElemX ) )
3908|      ((CadPrim*)p->p)->SetHold( false );
3909|    ListX_toEmptyDelete( &m_MultiHolds, ListX_ElemX, NULL );
3910|    for ( ListX_forEach( &m_MultiBefore, &p, ListX_ElemX) )
3911|      delete  (CadPrim*)p->p;
3912|    ListX_toEmptyDelete( &m_MultiBefore, ListX_ElemX, NULL );
3913|    if ( m_HoldStrokes != NULL )  { m_HoldStrokes->Release();  m_HoldStrokes = NULL; }
3914|
3915|    line = NULL;
3916|    switch ( mode ) {
3917|     case CMainFrame_CreateLine:
3918|       if ( frame->m_LineDesign != NULL )
3919|         line = (Line_Ex*)frame->m_LineDesign->GetNewCopy( &app->m_file.m_prims );
3920|       break;
3921|     case CMainFrame_CreateArrow:
3922|       if ( frame->m_ArrowDesign != NULL )
3923|         line = (Line_Ex*)frame->m_ArrowDesign->GetNewCopy( &app->m_file.m_prims );
3924|       break;
3925|     case CMainFrame_CreateGuideLine:
3926|       if ( frame->m_GuideLineArrowDesign != NULL )
3927|         line = (Line_Ex*)frame->m_GuideLineArrowDesign->GetNewCopy( &app->m_file.m_prims );
3928|       break;
3929|    }
3930|    if ( line != NULL ) {
3931|      line->m_id = app->GetNewPrimID();
3932|      line->m_bHold = true;
3933|      Line_init( &line->m_Line, point.x, point.y, point.x, point.y );
3934|    }
3935|    else {
3936|      line = new Line_Ex;
3937|      line->m_id = app->GetNewPrimID();
3938|      line->m_bHold = true;
3939|      Line_init( &line->m_Line, point.x, point.y, point.x, point.y );
3940|      line->m_Width = ( mode == CMainFrame_CreateGuideLine ? 2 : 1 );
3941|      line->m_Color = 0;
3942|      if ( mode == CMainFrame_CreateGuideLine )
3943|        line->m_Arrow1 = 2;
3944|      else if ( mode == CMainFrame_CreateArrow )
3945|        line->m_Arrow2 = 1;
3946|    }
3947|
3948|    /* ガイドラインなら枠付きテキストとリンクする */
3949|    if ( mode == CMainFrame_CreateGuideLine ) {
3950|
3951|      Text_Box*  text;
3952|      RECT  rc;
3953|      CadPrim_DrawParam  p;
3954|
3955|      text = NULL;
3956|      if ( frame->m_GuideLineTextDesign != NULL ) {
3957|        text = (Text_Box*)frame->m_GuideLineTextDesign->GetNewCopy( &app->m_file.m_prims );
3958|        text->m_id = app->GetNewPrimID();
3959|        text->m_IdLabel = "";
3960|        text->m_CenterX = point.x;
3961|        text->m_Y = point.y;
3962|      }
3963|      else {
3964|        text = new Text_Box;
3965|        text->m_id = app->GetNewPrimID();
3966|        text->m_Text = "ABC";
3967|        text->m_CenterX = point.x;
3968|        text->m_Y = point.y;
3969|        text->m_W = 100;  text->m_10H = 320;
3970|        text->m_Color = 0;
3971|        text->m_Font = _DefaultFont;
3972|        text->m_Size = 10;
3973|        text->m_bBold = false;  text->m_bItalic = false;
3974|        text->m_BoxShape = Text_Box_RectShape;
3975|        text->m_BoxMarginX = 4;  text->m_BoxMarginY = 2;
3976|        text->m_BorderWidth = 0;
3977|        text->m_BorderColor = 0x000000;
3978|        text->m_FillColor = 0xFFFFFF;
3979|      }
3980|      app->AddPrim( &app->m_file, line );
3981|      app->AddPrim( &app->m_file, text );
3982|
3983|      GetDrawParam( &p );
3984|      text->Draw( &m_MinBitmapDC, &p );
3985|      text->LinkToHandle( 0, line, 2 );
3986|
3987|      DrawAll( &m_BitmapDC, true );
3988|      text->GetBox( &rc );
3989|      rc.left = (rc.left + rc.right) / 2;
3990|      rc.top = (rc.top + rc.bottom) / 2;
3991|
3992|      m_DragPrim = line;
3993|      m_DragPrim->SetHold( false );
3994|      m_HoldPrim = text;
3995|      m_HoldPrim->SetHold( true );
3996|      m_BeforePrim = NULL;
3997|      m_iHoldHandle = -1;
3998|      frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
3999|    }
4000|
4001|    /* 開始地点が枠付きテキストならリンクする */
4002|    else {
4003|      m_DragPrim = line;
4004|      app->AddPrim( &app->m_file, line );
4005|
4006|      m_HoldPrim = line;
4007|      m_HoldPrim->SetHold( true );
4008|      m_iHoldHandle = 2;
4009|      frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
4010|    }
4011|    ListX_toEmptyDelete( &m_MultiHolds, ListX_ElemX, NULL );
4012|    p = ListX_addLastMalloc( &m_MultiHolds, ListX_ElemX );
4013|    p->p = m_HoldPrim;
4014|    SetMultiSelect();
4015|    m_Hold_dx = 0;  m_Hold_dy = 0;
4016|    m_DownX = -9999;  m_DownY = -9999;
4017|    m_bCreate = TRUE;
4018|    m_bDrag = TRUE;
4019|    m_bInDragPlay = TRUE;
4020|    break;
4021|   }
4022|
4023|   case CMainFrame_CreateLineCorner: {
4024|
4025|    Line_Corner*  line;
4026|    ListX_ElemX*  p;
4027|
4028|    app->m_file.m_Canvas.ChgToGridedPos( (int*)&point.x, (int*)&point.y );
4029|    AutoAdjustXY( &point.x, &point.y, true, false );
4030|
4031|    for ( ListX_forEach( &m_MultiHolds, &p, ListX_ElemX ) )
4032|      ((CadPrim*)p->p)->SetHold( false );
4033|    ListX_toEmptyDelete( &m_MultiHolds, ListX_ElemX, NULL );
4034|    for ( ListX_forEach( &m_MultiBefore, &p, ListX_ElemX) )
4035|      delete  (CadPrim*)p->p;
4036|    ListX_toEmptyDelete( &m_MultiBefore, ListX_ElemX, NULL );
4037|    if ( m_HoldStrokes != NULL )  { m_HoldStrokes->Release();  m_HoldStrokes = NULL; }
4038|
4039|    if ( frame->m_CorneredLineDesign != NULL ) {
4040|      line = (Line_Corner*)frame->m_CorneredLineDesign->GetNewCopy( &app->m_file.m_prims );
4041|      line->m_id = app->GetNewPrimID();
4042|      line->m_bHold = true;
4043|      Line_init( &line->m_Line, point.x, point.y, point.x, point.y );
4044|      line->m_CornerX = point.x;  line->m_CornerY = point.y;
4045|    }
4046|    else {
4047|      line = new Line_Corner;
4048|      line->m_id = app->GetNewPrimID();
4049|      line->m_bHold = true;
4050|      Line_init( &line->m_Line, point.x, point.y, point.x, point.y );
4051|      line->m_CornerX = point.x;  line->m_CornerY = point.y;
4052|      line->m_SlideCorner = true;
4053|      line->m_Dir = Line_DirN;
4054|      line->m_Width = 1;
4055|      line->m_Color = 0;
4056|    }
4057|
4058|    /* 開始地点が枠付きテキストならリンクする */
4059|    for ( ListX_forEach( &app->m_file.m_prims, &p, ListX_ElemX ) ) {
4060|      iHandle = ((CadPrim*)p->p)->GetLinkableHandleNum( point.x, point.y );
4061|      if ( iHandle != 0 )
4062|        break;
4063|    }
4064|    if ( p == NULL || app->m_file.m_Canvas.m_bGridOn ) {
4065|      m_DragPrim = line;
4066|    }
4067|    else {
4068|      m_BeforePrim = ((CadPrim*)p->p)->GetNewCopy( &app->m_file.m_prims );
4069|      m_BeforePrim->SetBInUndoBuf( true );
4070|      m_DragPrim = (CadPrim*)p->p;
4071|      ((Text_Box*)m_DragPrim)->ChangeAlign( Text_Box_CenterAlign );
4072|      ((CadPrim*)p->p)->LinkToHandle( iHandle, line, 1 );
4073|    }
4074|    app->AddPrimToBottomLine( &app->m_file, line );
4075|
4076|    m_HoldPrim = line;
4077|    m_iHoldHandle = 2;
4078|    ListX_toEmptyDelete( &m_MultiHolds, ListX_ElemX, NULL );
4079|    p = ListX_addLastMalloc( &m_MultiHolds, ListX_ElemX );
4080|    p->p = m_HoldPrim;
4081|    SetMultiSelect();
4082|    m_Hold_dx = 0;  m_Hold_dy = 0;
4083|    m_DownX = -9999;  m_DownY = -9999;
4084|    m_bCreate = TRUE;
4085|    m_bDrag = TRUE;
4086|    m_bInDragPlay = TRUE;
4087|    frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
4088|    break;
4089|   }
4090|
4091|   case CMainFrame_CreateRect:
4092|   case CMainFrame_CreateRoundRect:
4093|   case CMainFrame_CreateCircle:
4094|   case CMainFrame_CreateTransCircle:
4095|   case CMainFrame_CreateDiamond:
4096|   case CMainFrame_CreateImage: {
4097|
4098|    Rect_Ex*  rect;
4099|    ListX_ElemX*  p;
4100|
4101|    app->m_file.m_Canvas.ChgToGridedPos( (int*)&point.x, (int*)&point.y );
4102|    AutoAdjustXY( &point.x, &point.y, true, false );
4103|
4104|    for ( ListX_forEach( &m_MultiHolds, &p, ListX_ElemX ) )
4105|      ((CadPrim*)p->p)->SetHold( false );
4106|    ListX_toEmptyDelete( &m_MultiHolds, ListX_ElemX, NULL );
4107|    for ( ListX_forEach( &m_MultiBefore, &p, ListX_ElemX) )
4108|      delete  (CadPrim*)p->p;
4109|    ListX_toEmptyDelete( &m_MultiBefore, ListX_ElemX, NULL );
4110|    if ( m_HoldStrokes != NULL )  { m_HoldStrokes->Release();  m_HoldStrokes = NULL; }
4111|
4112|    rect = NULL;
4113|    switch ( mode ) {
4114|     case CMainFrame_CreateRect:
4115|       if ( frame->m_RectDesign != NULL )
4116|         rect = (Rect_Ex*)frame->m_RectDesign->GetNewCopy( &app->m_file.m_prims );
4117|       break;
4118|     case CMainFrame_CreateRoundRect:
4119|       if ( frame->m_RoundRectDesign != NULL )
4120|         rect = (Rect_Ex*)frame->m_RoundRectDesign->GetNewCopy( &app->m_file.m_prims );
4121|       break;
4122|     case CMainFrame_CreateCircle:
4123|       if ( frame->m_CircleDesign != NULL )
4124|         rect = (Rect_Ex*)frame->m_CircleDesign->GetNewCopy( &app->m_file.m_prims );
4125|       break;
4126|     case CMainFrame_CreateTransCircle:
4127|       if ( frame->m_StrongerDesign != NULL )
4128|         rect = (Rect_Ex*)frame->m_StrongerDesign->GetNewCopy( &app->m_file.m_prims );
4129|       break;
4130|     case CMainFrame_CreateDiamond:
4131|       if ( frame->m_DiamondDesign != NULL )
4132|         rect = (Rect_Ex*)frame->m_DiamondDesign->GetNewCopy( &app->m_file.m_prims );
4133|       break;
4134|    }
4135|    if ( rect != NULL ) {
4136|      rect->m_id = app->GetNewPrimID();
4137|      rect->m_IdLabel = "";
4138|      rect->m_bHold = true;
4139|      Rect_init( &rect->m_Rect, point.x, point.y, 1, 1 );
4140|    }
4141|    else {
4142|      rect = new Rect_Ex;
4143|      rect->m_id = app->GetNewPrimID();
4144|      rect->m_bHold = true;
4145|      Rect_init( &rect->m_Rect, point.x, point.y, 1, 1 );
4146|      rect->m_BorderWidth = 1;
4147|      rect->m_BorderColor = 0;
4148|      rect->m_FillColor = 0xFFFFFF;
4149|      switch ( mode ) {
4150|        case CMainFrame_CreateRect:  rect->m_ShapeType = Rect_RectShape;  break;
4151|        case CMainFrame_CreateRoundRect:  rect->m_ShapeType = Rect_RoundRectShape;  break;
4152|        case CMainFrame_CreateTransCircle:
4153|        case CMainFrame_CreateCircle:  rect->m_ShapeType = Rect_CircleShape;  break;
4154|        case CMainFrame_CreateDiamond:  rect->m_ShapeType = Rect_DiamondShape;  break;
4155|        case CMainFrame_CreateImage:  rect->m_ShapeType = Rect_ImageShape;  break;
4156|      }
4157|      if ( mode == CMainFrame_CreateTransCircle )  rect->m_NTrans = 0;
4158|    }
4159|    if ( mode == CMainFrame_CreateTransCircle )
4160|      app->AddPrimToTop( &app->m_file, rect );
4161|    else
4162|      app->AddPrim( &app->m_file, rect );
4163|
4164|    m_HoldPrim = rect;
4165|    m_DragPrim = rect;
4166|    m_iHoldHandle = 8;
4167|    ListX_toEmptyDelete( &m_MultiHolds, ListX_ElemX, NULL );
4168|    p = ListX_addLastMalloc( &m_MultiHolds, ListX_ElemX );
4169|    p->p = m_HoldPrim;
4170|    SetMultiSelect();
4171|    m_Hold_dx = 0;  m_Hold_dy = 0;
4172|    m_DownX = -9999;  m_DownY = -9999;
4173|    m_bCreate = TRUE;
4174|    m_bDrag = TRUE;
4175|    m_bInDragPlay = TRUE;
4176|    frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
4177|    break;
4178|   }
4179|
4180|   case CMainFrame_CreateMatome: {
4181|
4182|    Matome*  mato;
4183|    ListX_ElemX*  p;
4184|
4185|    app->m_file.m_Canvas.ChgToGridedPos( (int*)&point.x, (int*)&point.y );
4186|    AutoAdjustXY( &point.x, &point.y, true, false );
4187|
4188|    for ( ListX_forEach( &m_MultiHolds, &p, ListX_ElemX ) )
4189|      ((CadPrim*)p->p)->SetHold( false );
4190|    ListX_toEmptyDelete( &m_MultiHolds, ListX_ElemX, NULL );
4191|    for ( ListX_forEach( &m_MultiBefore, &p, ListX_ElemX) )
4192|      delete  (CadPrim*)p->p;
4193|    ListX_toEmptyDelete( &m_MultiBefore, ListX_ElemX, NULL );
4194|    if ( m_HoldStrokes != NULL )  { m_HoldStrokes->Release();  m_HoldStrokes = NULL; }
4195|
4196|    mato = new Matome;
4197|    mato->m_id = app->GetNewPrimID();
4198|    mato->m_bHold = true;
4199|    mato->m_x1 = point.x;  mato->m_y1 = point.y;
4200|    mato->m_x2 = point.x;  mato->m_y2 = point.y;
4201|    mato->m_BorderWidth = 1;
4202|    mato->m_BorderColor = 0;
4203|    app->AddPrimToTop( &app->m_file, mato );
4204|
4205|    m_HoldPrim = mato;
4206|    m_DragPrim = mato;
4207|    m_iHoldHandle = 8;
4208|    ListX_toEmptyDelete( &m_MultiHolds, ListX_ElemX, NULL );
4209|    p = ListX_addLastMalloc( &m_MultiHolds, ListX_ElemX );
4210|    p->p = m_HoldPrim;
4211|    SetMultiSelect();
4212|    m_Hold_dx = 0;  m_Hold_dy = 0;
4213|    m_DownX = -9999;  m_DownY = -9999;
4214|    m_bCreate = TRUE;
4215|    m_bDrag = TRUE;
4216|    m_bInDragPlay = TRUE;
4217|    frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
4218|    break;
4219|   }
4220|
4221|   case CMainFrame_Zooming: {
4222|    RECT  rect;
4223|
4224|    ReleaseCapture();
4225|    m_Zoom = m_ZoomNext;
4226|    m_ZoomMode = CChildView_ZoomNormal;
4227|    SetScrollSize();
4228|    GetClientRect( &rect );
4229|    point.x = point.x * m_Zoom / 100 - rect.right / 2;
4230|    point.y = point.y * m_Zoom / 100 - rect.bottom / 2;
4231|    ScrollToPosition( point );
4232|    frame->SetMode( m_ModeBeforeZoom );
4233|    m_bFirstCreate = false;
4234|    m_bBitmap = false;
4235|    DrawBackBitmap();
4236|    Invalidate( FALSE );
4237|    break;
4238|   }
4239|  }
4240|
4241|  if ( m_HoldPrim != NULL || ( m_bHitInk &&
4242|        mode == CMainFrame_Select || mode == CMainFrame_SelectMulti ) ) {
4243|    if ( m_bEditorEnable )  SetCursor( NULL );
4244|    else  SetCursor( app->LoadCursor( IDC_CursorHold ) );
4245|  }
4246|
4247|  ERRORS_FUNC_END_CPP( CChildView_OnLButtonDown );
4248|}
4249|
4250|
4251| 
4252|/***********************************************************************
4253|  37. <<< [CChildView::OnLButtonDblClk] ダブルクリックを開始する >>> 
4254|【補足】
4255|・ダブルクリックの主な処理は、CChildView::OnLButtonUp で行っています。
4256|************************************************************************/
4257|void CChildView::OnLButtonDblClk(UINT nFlags, CPoint point)
4258|{
4259|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
4260|  CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
4261|  bool  bShift = ( nFlags & MK_SHIFT ) != 0;
4262|  bool  bCtrl = ( nFlags & MK_CONTROL ) != 0;
4263|  CadPrim*  prim;
4264|  POINT  pt;
4265|  ERRORS_FUNC_CPP_VAR( CChildView_OnLButtonDblClk );
4266|  ERRORS_FUNC_START_CPP( CChildView_OnLButtonDblClk );
4267|
4268|  if ( m_SingleDblClickTimer != 0 )  frame->KillTimer( m_SingleDblClickTimer );
4269|  m_SingleDblClickTimer = 0;
4270|
4271|  if ( frame->IsPenMode() ) {
4272|    OnLButtonDown( nFlags, point );
4273|    ERRORS_FUNC_END_CPP( CChildView_OnLButtonDblClk );
4274|    return;
4275|  }
4276|
4277|  pt = GetScrollPosition();
4278|  point += pt;
4279|  point -= m_MinusOffset;
4280|  point.x = point.x * 100 / m_Zoom;
4281|  point.y = point.y * 100 / m_Zoom;
4282|
4283|  SetCapture();
4284|  m_bDblDrag = TRUE;
4285|  m_bDrag = FALSE;
4286|  m_bInDragPlay = TRUE;
4287|
4288|  {
4289|    int  iHandle, dx, dy, arrow;
4290|    prim = app->GetNearestHandle( point.x, point.y, m_Zoom, frame->GetCadPrimMode(),
4291|      &iHandle, &dx, &dy, &arrow, m_HoldPrim );
4292|  }
4293|
4294|  /* ダブルクリックでテキストを生成する */
4295|  if ( prim == NULL || m_HoldPrim == NULL ||
4296|       ( m_HoldPrim->GetTypeID() != Line_Corner_TypeID &&
4297|         m_HoldPrim->GetTypeID() != Text_Box_TypeID ) ) {
4298|    Text_Box*  text;
4299|    ListX_ElemX*  p;
4300|    RECT  rc;
4301|
4302|    for ( ListX_forEach( &m_MultiHolds, &p, ListX_ElemX ) )
4303|      ((CadPrim*)p->p)->SetHold( false );
4304|    ListX_toEmptyDelete( &m_MultiHolds, ListX_ElemX, NULL );
4305|    m_HoldPrim = NULL;
4306|    for ( ListX_forEach( &m_MultiBefore, &p, ListX_ElemX) )
4307|      delete  (CadPrim*)p->p;
4308|    ListX_toEmptyDelete( &m_MultiBefore, ListX_ElemX, NULL );
4309|
4310|    text = new Text_Box;
4311|    text->m_id = app->GetNewPrimID();
4312|    text->m_bHold = true;
4313|    text->m_Text = "ABC";
4314|    text->m_CenterX = point.x;  text->m_Y = point.y;  /* 仮位置 */
4315|    text->m_W = 100;  text->m_10H = 320;
4316|    text->m_Color = 0;
4317|    text->m_Font = _DefaultFont;
4318|    text->m_Size = 10;
4319|    text->m_bBold = false;  text->m_bItalic = false;
4320|    if ( bCtrl )  text->m_BoxShape = bShift ? Text_Box_CircleShape : Text_Box_RectShape;
4321|    else  text->m_BoxShape = bShift ? Text_Box_DiamondShape : Text_Box_NoFrame;
4322|    if ( text->m_BoxShape == Text_Box_DiamondShape ) {
4323|      text->m_BoxMarginX = 28;  text->m_BoxMarginY = 6;
4324|      text->m_BasePos = Text_Box_CenterAlign;
4325|    }
4326|    else if ( text->m_BoxShape == Text_Box_CircleShape ) {
4327|      text->m_BoxMarginX = 10;  text->m_BoxMarginY = 6;
4328|      text->m_BasePos = Text_Box_CenterAlign;
4329|    }
4330|    else if ( text->m_BoxShape == Text_Box_NoFrame ) {
4331|      text->m_BoxMarginX = 2;  text->m_BoxMarginY = 2;
4332|      text->m_BasePos = Text_Box_LeftAlign;
4333|    }
4334|    else {
4335|      text->m_BoxMarginX = 8;  text->m_BoxMarginY = 6;
4336|      text->m_BasePos = Text_Box_CenterAlign;
4337|    }
4338|    text->m_BorderWidth = 1;
4339|    text->m_BorderColor = 0x000000;
4340|    text->m_FillColor = 0xFFFFFF;
4341|    app->AddPrim( &app->m_file, text );
4342|
4343|    DrawAll( &m_BitmapDC, true );
4344|    text->GetBox( &rc );
4345|    text->m_CenterX -= ( rc.left + rc.right ) / 2 - point.x;
4346|    text->m_Y -= ( rc.top + rc.bottom ) / 2 - point.y;
4347|                                     /* 仮位置からテキストの中心へずらす */
4348|    app->m_file.m_Canvas.ChgToGridedPos( &text->m_CenterX, &text->m_Y );  text->m_Y -= Text_Box_GridGap;
4349|
4350|    m_HoldPrim = text;
4351|    m_DragPrim = text;
4352|    m_iHoldHandle = -1;
4353|    p = ListX_addLastMalloc( &m_MultiHolds, ListX_ElemX );
4354|    p->p = m_HoldPrim;
4355|    SetMultiSelect();
4356|    m_Hold_dx = 0;  m_Hold_dy = 0;
4357|    m_DownX = point.x;  m_DownY = point.y;
4358|
4359|    m_bCreate = TRUE;
4360|    frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
4361|  }
4362|
4363|  /* シフトキーを押しながらダブルクリックしたときは、選択されないことがある */
4364|  if ( m_HoldPrim == NULL && prim != NULL &&
4365|       ListX_getN( &m_MultiHolds, ListX_ElemX ) == 0 ) {
4366|    ListX_ElemX*  p;
4367|
4368|    m_HoldPrim = prim;
4369|    m_DragPrim = prim;
4370|    m_iHoldHandle = -1;
4371|    p = ListX_addLastMalloc( &m_MultiHolds, ListX_ElemX );
4372|    p->p = m_HoldPrim;
4373|    SetMultiSelect();
4374|    m_Hold_dx = 0;  m_Hold_dy = 0;
4375|    m_DownX = -9999;  m_DownY = -9999;
4376|    frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
4377|  }
4378|
4379|  CScrollView::OnLButtonDblClk(nFlags, point);
4380|
4381|  ERRORS_FUNC_END_CPP( CChildView_OnLButtonDblClk );
4382|}
4383|
4384|
4385| 
4386|/***********************************************************************
4387|  38. <<< [CChildView::OnLButtonUp] マウスの左ボタンを離したとき >>> 
4388|************************************************************************/
4389|void CChildView::OnLButtonUp(UINT nFlags, CPoint point)
4390|{
4391|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
4392|  CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
4393|
4394|  EndDragScroll();
4395|
4396|  if ( frame->IsPenMode() && m_HoldPrim != &app->m_file.m_Canvas )
4397|    return;
4398|
4399|  bool  bAddedUndoBuf = false;
4400|  bool  bDblDlag = (m_bDblDrag != 0);
4401|  POINT  pt;
4402|  BOOL   bInDragPlay = m_bInDragPlay;
4403|  ERRORS_FUNC_CPP_VAR( CChildView_OnLButtonUp );
4404|  ERRORS_FUNC_START_CPP( CChildView_OnLButtonUp );
4405|
4406|  if ( ! m_bDrag && ! m_bDblDrag ) {
4407|    ReleaseCapture();
4408|    CScrollView ::OnLButtonUp(nFlags, point);
4409|    ERRORS_FUNC_END_CPP( CChildView_OnLButtonUp );
4410|    return;
4411|  }
4412|
4413|  m_ClickUpTime1 = m_ClickUpTime2;
4414|  m_ClickUpTime2 = GetTickCount();
4415|
4416|  pt = GetScrollPosition();
4417|  point += pt;
4418|  point -= m_MinusOffset;
4419|  point.x = point.x * 100 / m_Zoom;
4420|  point.y = point.y * 100 / m_Zoom;
4421|  m_UpS = point;
4422|
4423|  ReleaseCapture();
4424|
4425|  if ( m_HoldPrim != NULL ) {
4426|
4427|    /* 新規作成したとき */
4428|    if ( m_bCreate ) {
4429|      OnLButtonUp_Create( nFlags, point );
4430|    }
4431|
4432|    /* ダブルクリック、もしくはダブル・クリック・ドラッグを終了したとき */
4433|    else if ( m_bDblDrag ) {
4434|      OnLButtonUp_DblDlagPrim( nFlags, point );
4435|    }
4436|
4437|    /* シングルクリック、もしくは単純ドラッグを終了したとき */
4438|    else {
4439|      OnLButtonUp_DlagPrim( nFlags, point );
4440|    }
4441|  }
4442|  else {
4443|    OnLButtonUp_DlagCanvas( nFlags, point );
4444|  }
4445|
4446|  #ifdef  USES_INK
4447|  if ( m_HoldInk != NULL ) {
4448|    m_HoldInk->ScratchEnd();
4449|    m_HoldInk = NULL;
4450|    m_bCreate = FALSE;
4451|    m_bDrag = FALSE;
4452|    m_iHoldHandle = 0;
4453|    bAddedUndoBuf = true;
4454|  }
4455|  #endif
4456|
4457|  /* アンドゥバッファに記録する */
4458|  if ( !m_bCreate &&  ( m_BeforePrim != NULL || m_bHitInk || m_iHoldHandle == -3 ) ) {
4459|    ListX_ElemX*  p;
4460|    ListX_ElemX*  p2;
4461|
4462|    if ( m_BeforePrim != NULL && ListX_getN( &m_MultiHolds, ListX_ElemX ) == 0 ) {
4463|      app->m_UndoBuf->AllocNewStep( m_BeforePrim,  /* このルートはキャンバスのリサイズがある */
4464|        m_HoldPrim->GetNewCopy( &app->m_file.m_prims ), NULL, NULL, app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
4465|    }
4466|    else {
4467|      app->m_UndoBuf->StartMulti();
4468|      p2 = ListX_getFirst( &m_MultiBefore, ListX_ElemX );
4469|      for ( ListX_forEach( &m_MultiSelects, &p, ListX_ElemX ) ) {
4470|        app->m_UndoBuf->AllocNewStep( (CadPrim*)p2->p,
4471|          ((CadPrim*)p->p)->GetNewCopy( &app->m_file.m_prims ), NULL, NULL, app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
4472|        p2 = ListX_Elem_getNextT( p2, ListX_ElemX );
4473|      }
4474|      if ( m_HoldStrokes != NULL ) {
4475|        IInkStrokes*  strokes = DuplicateStrokes( m_HoldStrokes );
4476|        IInkRenderer*  render;
4477|        IInkDisp*  ink;
4478|        CClientDC  dc(this);
4479|        long  dx, dy;
4480|        HRESULT  hr;
4481|
4482|        hr = m_InkOverlay->get_Renderer( &render ); if ( hr != 0 )  error();
4483|        hr = m_InkOverlay->get_Ink( &ink ); if ( hr != 0 )  error();
4484|
4485|        if ( m_iHoldHandle == -3 ) {
4486|          dx = (m_UpS.x - m_DownS.x) - m_Hold_dx - pt.x;  dy = (m_UpS.y - m_DownS.y) - m_Hold_dy - pt.y;
4487|          hr = render->Move( -m_prevX0, -m_prevY0 ); if ( hr != 0 )  error();
4488|          hr = render->ScaleTransform( (float)100 / m_Zoom, (float)100 / m_Zoom ); if ( hr != 0 )  error();
4489|          hr = render->PixelToInkSpace( (long)dc.m_hDC, &dx, &dy ); if ( hr != 0 )  error();
4490|          hr = render->ScaleTransform( (float)m_Zoom / 100, (float)m_Zoom / 100 ); if ( hr != 0 )  error();
4491|          hr = render->Move( m_prevX0, m_prevY0 ); if ( hr != 0 )  error();
4492|
4493|          app->m_UndoBuf->AllocNewStep_Ink( Undo_Ink_Resize, ink, strokes,
4494|            dx, dy, app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
4495|        }
4496|        else {
4497|          dx = m_UpS.x - m_DownS.x - pt.x;  dy = m_UpS.y - m_DownS.y - pt.y;
4498|          hr = render->Move( -m_prevX0, -m_prevY0 ); if ( hr != 0 )  error();
4499|          hr = render->ScaleTransform( (float)100 / m_Zoom, (float)100 / m_Zoom ); if ( hr != 0 )  error();
4500|          hr = render->PixelToInkSpace( (long)dc.m_hDC, &dx, &dy ); if ( hr != 0 )  error();
4501|          hr = render->ScaleTransform( (float)m_Zoom / 100, (float)m_Zoom / 100 ); if ( hr != 0 )  error();
4502|          hr = render->Move( m_prevX0, m_prevY0 ); if ( hr != 0 )  error();
4503|             /* 100% に戻してから変換する */
4504|
4505|          app->m_UndoBuf->AllocNewStep_Ink( Undo_Ink_Move, ink, strokes,
4506|            dx, dy, app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
4507|        }
4508|        hr = ink->Release();  ink = NULL;
4509|        hr = render->Release();  render = NULL;
4510|      }
4511|      app->m_UndoBuf->EndMulti();
4512|      ListX_toEmptyDelete( &m_MultiBefore, ListX_ElemX, NULL );
4513|      if ( m_BeforePrim != NULL )  delete  m_BeforePrim;
4514|    }
4515|    m_BeforePrim = NULL;
4516|  }
4517|
4518|  m_bDrag = FALSE;
4519|  m_bDblDrag = FALSE;
4520|  m_bInDragPlay = FALSE;
4521|  m_bDragGrided = FALSE;
4522|  m_bCreate = FALSE;
4523|  m_bFirstCreate = FALSE;
4524|  SetCursorSVGCats( point );
4525|  SetCursor( m_Cursor );
4526|
4527|  if ( m_HoldPrim != NULL && ! m_bInDragPlay ) {
4528|    m_bInDragPlay = TRUE;  /* ハンドルを描画するため */
4529|    Redraw( false );
4530|  }
4531|
4532|
4533|  #if  ERRORS_DEBUG_FALSE
4534|  {
4535|    ListX_ElemX*  p;
4536|
4537|    MARK();
4538|    app->printPrims(&app->m_file.m_prims,"");
4539|
4540|    Errors_printf( "---- MultiBefore ----------------------" );
4541|    for ( ListX_forEach( &m_MultiBefore, &p, ListX_ElemX ) ) {
4542|      ((CadPrim*)p->p)->print( "" );
4543|    }
4544|  }
4545|  #endif
4546|
4547|  DrawOutOfCanvas( &m_BitmapDC );
4548|
4549|  if ( app->m_bSingleClick && m_iHoldHandle != -2 && m_bSelectedClick &&
4550|      ! bDblDlag && bInDragPlay && ! m_bUnholdable ) {
4551|    int  time = GetDoubleClickTime();
4552|
4553|    m_SingleDblClickTimer = frame->SetTimer( CMainFrame_Timer_SingleDblClick,
4554|      time < 500 ? time : time / 2, NULL );
4555|  }
4556|
4557|  CScrollView ::OnLButtonUp(nFlags, point);
4558|
4559|  ERRORS_FUNC_END_CPP( CChildView_OnLButtonUp );
4560|}
4561|
4562|	
4563|void  CChildView::OnLButtonUp_Create(UINT nFlags, CPoint point) 
4564|{
4565|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
4566|  CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
4567|  CadPrim*  linkPrim1 = NULL;
4568|  CadPrim*  linkPrim2 = NULL;
4569|  CadPrim*  beforePrim1;
4570|  CadPrim*  beforePrim2;
4571|  ListX_ElemX*  p;
4572|  int  iHandle;
4573|  bool  bAddedUndoBuf = false;
4574|
4575|  m_HoldPrim->OnCreated();
4576|
4577|  if ( m_BeforePrim != NULL ) {
4578|    app->m_UndoBuf->AllocNewStep( m_BeforePrim, m_DragPrim->GetNewCopy( &app->m_file.m_prims ),
4579|      NULL, NULL, app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
4580|    m_BeforePrim = NULL;
4581|  }
4582|
4583|  app->m_UndoBuf->StartMulti();
4584|
4585|  switch ( m_HoldPrim->GetTypeID() ) {
4586|
4587|   /* テキスト、ガイドラインを生成したとき */
4588|   case  Text_Box_TypeID: {
4589|    Line_Ex*  guideLine = NULL;
4590|    CWaitCursor  wa;
4591|
4592|    if (  m_DragPrim->GetTypeID() == Line_Ex_TypeID )
4593|      guideLine = (Line_Ex*)m_DragPrim;
4594|
4595|    if ( guideLine != NULL ) {
4596|
4597|      /* その場でクリックしたらテキストをずらす */
4598|      if ( abs( guideLine->m_Line.x1 - point.x ) < 20 &&
4599|           abs( guideLine->m_Line.y1 - point.y ) < 15 ) {
4600|        guideLine->m_Line.x2 = guideLine->m_Line.x1 + 40;
4601|        guideLine->m_Line.y2 = guideLine->m_Line.y1 + 30;
4602|        point.x = guideLine->m_Line.x2;
4603|        point.y = guideLine->m_Line.y2;
4604|        app->m_file.m_Canvas.ChgToGridedPos( (int*)&point.x, (int*)&point.y );
4605|        point.y -= Text_Box_GridGap;
4606|        m_HoldPrim->MoveByHandle( m_iHoldHandle, point.x, point.y, false, false );
4607|      }
4608|    }
4609|
4610|    if ( frame->m_mode != CMainFrame_CreateTimeStamp ) {
4611|      if ( 0 && m_InkOverlay != NULL ) {
4612|        CInputML  dlg;
4613|        Text_Box*  prim = (Text_Box*)m_HoldPrim;
4614|
4615|        dlg.m_ID = (void*)prim->GetID();
4616|        dlg.m_Text = prim->m_Text;
4617|        dlg.m_PenInputPanel = m_PenInputPanel;
4618|        dlg.m_bDispPenPanel = m_bInputML_bDispPenPanel;
4619|        dlg.m_CursorPos = m_DownS;   dlg.m_CursorPos -= GetScrollPosition();
4620|        ClientToScreen( &dlg.m_CursorPos );
4621|        dlg.m_SaveObj = this;  dlg.m_SaveFunc = (CInputML_SaveF)CChildView_saveOnEditing;
4622|        dlg.m_bCtrlRet = app->m_bCtrlRet;
4623|        dlg.m_bJapanese = app->m_bJapanese;
4624|        dlg.m_bHideMain = app->m_bHideMain;
4625|        dlg.m_HideTarget = frame;
4626|        dlg.m_ShowWindowFunc = (CInputML_ShowWindowF)CMainFrame_ShowWindowFunc;
4627|        dlg.m_kword = frame->m_KWord;
4628|        if ( frame->m_mode == CMainFrame_CreateTimeStamp )
4629|          dlg.m_bNoSelect = true;
4630|        m_InputML = &dlg;
4631|        m_bInDragPlay = TRUE;  /* ハンドルも表示する */
4632|
4633|        Redraw( false );
4634|
4635|        if ( dlg.DoModal() == IDOK ) {
4636|          m_InputML = NULL;
4637|          prim->m_Text = dlg.m_Text;
4638|          frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
4639|          if ( guideLine != NULL ) {  /* ガイドラインもアンドゥに含める */
4640|            app->m_UndoBuf->AllocNewStep( NULL, m_HoldPrim->GetNewCopy( &app->m_file.m_prims ),
4641|              NULL, NULL, app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
4642|            app->m_UndoBuf->AllocNewStep( NULL, guideLine->GetNewCopy( &app->m_file.m_prims ),
4643|              NULL, NULL, app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
4644|            bAddedUndoBuf = true;
4645|
4646|            { /* ラインリンクを調整する */
4647|              CadPrim_DrawParam  pa;
4648|
4649|              GetDrawParam( &pa );
4650|              prim->Draw( &m_MinBitmapDC, &pa );  /* Text_Box の範囲を決定するため */
4651|              prim->Move( 0, 0 );  /* ラインリンクの調整 */
4652|            }
4653|          }
4654|        }
4655|        else {
4656|          m_InputML = NULL;
4657|          app->RemovePrim( &app->m_file, m_HoldPrim );
4658|          if ( guideLine != NULL )
4659|            app->RemovePrim( &app->m_file, guideLine );
4660|          m_HoldPrim = NULL;
4661|          ListX_toEmptyDelete( &m_MultiHolds, ListX_ElemX, NULL );
4662|          ResetSelect();
4663|          bAddedUndoBuf = true;
4664|          frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
4665|        }
4666|        m_bInputML_bDispPenPanel = dlg.m_bDispPenPanel;
4667|        app->m_bCtrlRet = dlg.m_bCtrlRet;
4668|        app->m_bHideMain = dlg.m_bHideMain;
4669|        frame->m_KWord = dlg.m_kword;
4670|      }
4671|      else {
4672|        CInputML1  dlg;
4673|        Text_Box*  prim = (Text_Box*)m_HoldPrim;
4674|
4675|        dlg.m_ID = (void*)prim->GetID();
4676|        dlg.m_Text = prim->m_Text;
4677|        dlg.m_PenInputPanel = m_PenInputPanel;
4678|        dlg.m_bDispPenPanel = m_bInputML_bDispPenPanel;
4679|        dlg.m_CursorPos = m_DownS;   dlg.m_CursorPos -= GetScrollPosition();
4680|        ClientToScreen( &dlg.m_CursorPos );
4681|        dlg.m_SaveObj = this;  dlg.m_SaveFunc = (CInputML1_SaveF)CChildView_saveOnEditing1;
4682|        dlg.m_bCtrlRet = app->m_bCtrlRet;
4683|        dlg.m_bJapanese = app->m_bJapanese;
4684|        dlg.m_bHideMain = app->m_bHideMain;
4685|        dlg.m_HideTarget = frame;
4686|        dlg.m_ShowWindowFunc = (CInputML1_ShowWindowF)CMainFrame_ShowWindowFunc;
4687|        dlg.m_kword = frame->m_KWord;
4688|        if ( frame->m_mode == CMainFrame_CreateTimeStamp )
4689|          dlg.m_bNoSelect = true;
4690|        m_InputML1 = &dlg;
4691|        m_bInDragPlay = TRUE;  /* ハンドルも表示する */
4692|
4693|        Redraw( false );
4694|
4695|        if ( dlg.DoModal() == IDOK ) {
4696|          m_InputML1 = NULL;
4697|          prim->m_Text = dlg.m_Text;
4698|          frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
4699|          if ( guideLine != NULL ) {  /* ガイドラインもアンドゥに含める */
4700|            app->m_UndoBuf->AllocNewStep( NULL, m_HoldPrim->GetNewCopy( &app->m_file.m_prims ),
4701|              NULL, NULL, app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
4702|            app->m_UndoBuf->AllocNewStep( NULL, guideLine->GetNewCopy( &app->m_file.m_prims ),
4703|              NULL, NULL, app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
4704|            bAddedUndoBuf = true;
4705|
4706|            { /* ラインリンクを調整する */
4707|              CadPrim_DrawParam  pa;
4708|
4709|              GetDrawParam( &pa );
4710|              prim->Draw( &m_MinBitmapDC, &pa );  /* Text_Box の範囲を決定するため */
4711|              prim->Move( 0, 0 );  /* ラインリンクの調整 */
4712|            }
4713|          }
4714|        }
4715|        else {
4716|          m_InputML1 = NULL;
4717|          app->RemovePrim( &app->m_file, m_HoldPrim );
4718|          if ( guideLine != NULL )
4719|            app->RemovePrim( &app->m_file, guideLine );
4720|          m_HoldPrim = NULL;
4721|          ListX_toEmptyDelete( &m_MultiHolds, ListX_ElemX, NULL );
4722|          ResetSelect();
4723|          bAddedUndoBuf = true;
4724|          frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
4725|        }
4726|        m_bInputML_bDispPenPanel = dlg.m_bDispPenPanel;
4727|        app->m_bCtrlRet = dlg.m_bCtrlRet;
4728|        app->m_bHideMain = dlg.m_bHideMain;
4729|        frame->m_KWord = dlg.m_kword;
4730|      }
4731|    }
4732|    break;
4733|   }
4734|
4735|   case  Line_Corner_TypeID:
4736|    ((Line_Corner*)m_HoldPrim)->m_SlideCorner = false;
4737|    /* continue to next line */
4738|
4739|   case  Line_Ex_TypeID:
4740|
4741|    /* キャンバスをダブルクリックして枠付きテキストを生成したとき */
4742|    if ( m_HoldPrim->GetTypeID() == Text_Box_TypeID &&
4743|         m_DragPrim->GetTypeID() == Text_Box_TypeID ) {
4744|      m_HoldPrim->UnlinkAll();  /* line */
4745|      app->RemovePrim( &app->m_file, m_HoldPrim );
4746|      delete  m_BeforePrim;
4747|      m_BeforePrim = NULL;
4748|      for ( ListX_forEach( &m_MultiBefore, &p, ListX_ElemX ) ) {
4749|        delete  (CadPrim*)p->p;
4750|      }
4751|      ListX_toEmptyDelete( &m_MultiBefore, ListX_ElemX, NULL );
4752|
4753|      m_HoldPrim = m_DragPrim;  /* m_bDblDrag によるテキスト入力へ */
4754|      Redraw( false );
4755|    }
4756|
4757|    else {
4758|      bool  bConfirm = false;
4759|      bool  bConfirmYes = false;
4760|
4761|      /* 生成した線の始点が枠付きテキストならリンクする */
4762|      for ( ListX_forEach( &app->m_file.m_prims, &p, ListX_ElemX ) ) {
4763|        iHandle = ((CadPrim*)p->p)->GetLinkableHandleNum(
4764|           ((Line_Ex*)m_HoldPrim)->m_Line.x1, ((Line_Ex*)m_HoldPrim)->m_Line.y1 );
4765|        if ( iHandle != 0 )
4766|          break;
4767|      }
4768|      if ( p != NULL ) {
4769|        bConfirmYes = ( MessageBox( app->m_bJapanese ? "生成したラインをテキストとリンクしますか?" :
4770|               "Do you link line to text?", "SVG Cats", MB_YESNO ) == IDYES );
4771|        bConfirm = true;
4772|        if ( ! bConfirmYes )  p = NULL;
4773|      }
4774|      if ( p != NULL ) {
4775|        beforePrim1 = ((CadPrim*)p->p)->GetNewCopy( &app->m_file.m_prims );
4776|        beforePrim1->SetBInUndoBuf( true );
4777|        m_DragPrim = (CadPrim*)p->p;
4778|        linkPrim1 = (CadPrim*)p->p;
4779|        ((Text_Box*)m_DragPrim)->ChangeAlign( Text_Box_CenterAlign );
4780|  
4781|        ((CadPrim*)p->p)->LinkToHandle( iHandle, m_HoldPrim, 1 ); 
4782|        m_HoldPrim->SetHold( false );
4783|        if ( ((CadPrim*)p->p)->GetTypeID() == Text_Box_TypeID )
4784|          ((Text_Box*)p->p)->MoveLinks( true );
4785|        m_HoldPrim->SetHold( true );
4786|      }
4787|
4788|      /* 生成した線の終点が枠付きテキストならリンクする */
4789|      for ( ListX_forEach( &app->m_file.m_prims, &p, ListX_ElemX ) ) {
4790|        if ( (CadPrim*)p->p == m_DragPrim )  continue;
4791|        iHandle = ((CadPrim*)p->p)->GetLinkableHandleNum( point.x, point.y );
4792|        if ( iHandle != 0 )
4793|          break;
4794|      }
4795|      if ( p != NULL ) {
4796|        if ( ! bConfirm ) {
4797|          bConfirmYes = ( MessageBox( app->m_bJapanese ? "生成したラインをテキストとリンクしますか?" :
4798|                 "Do you link line to text?", "SVG Cats", MB_YESNO ) == IDYES );
4799|          bConfirm = true;
4800|        }
4801|        if ( ! bConfirmYes )  p = NULL;
4802|      }
4803|      if ( p != NULL ) {
4804|        linkPrim2 = (CadPrim*)p->p;
4805|        ((Text_Box*)linkPrim2)->ChangeAlign( Text_Box_CenterAlign );
4806|        beforePrim2 = linkPrim2->GetNewCopy( &app->m_file.m_prims );
4807|        beforePrim2->SetBInUndoBuf( true );
4808|        linkPrim2->LinkToHandle( iHandle, m_HoldPrim, 2 );
4809|        m_HoldPrim->SetHold( false );
4810|        ((Text_Box*)linkPrim2)->MoveLinks( true );
4811|        m_HoldPrim->SetHold( true );
4812|      }
4813|
4814|      if ( bConfirmYes ) {
4815|        ZBottom( m_HoldPrim );
4816|      }
4817|    }
4818|    break;
4819|
4820|   case  Rect_Ex_TypeID: {
4821|    Rect_Ex*  rect = (Rect_Ex*)m_HoldPrim;
4822|
4823|    if ( frame->m_mode == CMainFrame_CreateImage ) {
4824|      char*  filter = ( app->m_bJapanese ? _image_filter : _image_filterE );
4825|      CFileDialog  dlg( TRUE, NULL, NULL, OFN_HIDEREADONLY, filter );
4826|
4827|      #ifdef  NDEBUG
4828|        dlg.m_ofn.Flags &= ~OFN_ENABLEHOOK;  /* Win2000以降の新しいファイルダイアログにする */
4829|      #endif
4830|      dlg.m_ofn.lpstrInitialDir = app->m_ImgFolderPath;
4831|
4832|      if ( dlg.DoModal() == IDOK ) {
4833|        rect->m_ImgPath = dlg.GetPathName();
4834|        rect->m_ImgWorkPath = app->GetImgWorkFilePath( (long)frame->m_hWnd );
4835|        StrX_cpyFolder( app->m_ImgFolderPath, dlg.GetPathName() );
4836|        DrawAll( &m_BitmapDC, true );
4837|        frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
4838|      }
4839|      else {
4840|        app->RemovePrim( &app->m_file, rect );
4841|        ResetSelect();
4842|        bAddedUndoBuf = true;
4843|      }
4844|    }
4845|    break;
4846|   }
4847|  }
4848|
4849|  /* リンクしたとき、アンドゥバッファに記録する */
4850|  if ( m_HoldPrim != NULL ) {
4851|    switch ( m_HoldPrim->GetTypeID() ) {
4852|     case  Line_Ex_TypeID:
4853|     case  Line_Corner_TypeID:
4854|
4855|      for ( ListX_forEach( &app->m_file.m_prims, &p, ListX_ElemX ) ) {
4856|        if ( (CadPrim*)p->p == m_HoldPrim )  break;
4857|      }
4858|      ASSERT( p != NULL );
4859|      p = ListX_Elem_getNextT( p, ListX_ElemX );
4860|      app->m_UndoBuf->AllocNewStep( NULL, m_HoldPrim->GetNewCopy( &app->m_file.m_prims ),
4861|        NULL, p == NULL ? NULL : ((CadPrim*)p->p)->GetNewCopy( &app->m_file.m_prims ),
4862|        app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
4863|
4864|      if ( linkPrim1 != NULL ) {
4865|        app->m_UndoBuf->AllocNewStep( beforePrim1, linkPrim1->GetNewCopy( &app->m_file.m_prims ),
4866|          NULL, NULL, app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
4867|      }
4868|      if ( linkPrim2 != NULL ) {
4869|        app->m_UndoBuf->AllocNewStep( beforePrim2, linkPrim2->GetNewCopy( &app->m_file.m_prims ),
4870|          NULL, NULL, app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
4871|      }
4872|
4873|      bAddedUndoBuf = true;
4874|      break;
4875|    }
4876|  }
4877|
4878|  if ( ! bAddedUndoBuf ) {
4879|    ListX_ElemX*  p;
4880|
4881|    for ( ListX_forEach( &app->m_file.m_prims, &p, ListX_ElemX ) ) {
4882|      if ( (CadPrim*)p->p == m_HoldPrim )
4883|        break;
4884|    }
4885|    ASSERT( p != NULL );
4886|    p = ListX_Elem_getNextT( p, ListX_ElemX );
4887|
4888|    app->m_UndoBuf->AllocNewStep( NULL,
4889|      m_HoldPrim->GetNewCopy( &app->m_file.m_prims ), NULL,
4890|      p == NULL ? NULL : ((CadPrim*)p->p)->GetNewCopy( &app->m_file.m_prims ),
4891|      app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
4892|  }
4893|
4894|  Redraw( false );
4895|  app->m_UndoBuf->EndMulti();
4896|  m_PrevCreateMode = frame->m_mode;
4897|}
4898|
4899| 
4900|void  CChildView::OnLButtonUp_DlagPrim(UINT nFlags, CPoint point) 
4901|{
4902|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
4903|  CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
4904|
4905|  /* スクロールの範囲を設定する */
4906|  if ( m_HoldPrim == &app->m_file.m_Canvas ) {
4907|    m_bDrag = FALSE;  /* SetScrollSize でスクロールサイズを小さくするため */
4908|    SetScrollSize();
4909|    Invalidate( false );
4910|  }
4911|
4912|  /* マルチセレクトモードのとき、ドラッグではなかったら選択を1つ解除する */
4913|  if ( m_bUnholdable && m_bInDragPlay ) {
4914|    ListX_ElemX*  p;
4915|
4916|    for ( ListX_forEach( &m_MultiHolds, &p, ListX_ElemX ) ) {
4917|      if ( p->p == m_HoldPrim )  break;
4918|    }
4919|    ASSERT( p != NULL );
4920|    m_HoldPrim->SetHold( false );
4921|    ListX_removeFree( &m_MultiHolds, p );
4922|    p = ListX_getFirst( &m_MultiHolds, ListX_ElemX );
4923|    m_HoldPrim = (CadPrim*)( p == NULL ? NULL : p->p );
4924|    m_DragPrim = NULL;
4925|    m_iHoldHandle = 0;
4926|    frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
4927|    if ( m_BeforePrim != NULL )  { delete  m_BeforePrim;  m_BeforePrim = NULL; }
4928|    for ( ListX_forEach( &m_MultiBefore, &p, ListX_ElemX ) ) {
4929|      delete  (CadPrim*)p->p;
4930|    }
4931|    ListX_finish2( &m_MultiBefore, ListX_ElemX, NULL );
4932|    Redraw( false );
4933|  }
4934|}
4935|
4936| 
4937|void  CChildView::OnLButtonUp_DlagCanvas(UINT nFlags, CPoint point) 
4938|{
4939|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
4940|  CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
4941|
4942|  /* ドラッグによる複数選択(トグル) */
4943|  if ( m_iHoldHandle == 2 ) {
4944|    ListX_ElemX*  p;
4945|    ListX_ElemX*  p2;
4946|    Rect  rc;
4947|
4948|    Rect_init_by2XY( &rc,
4949|      m_DownX < point.x ? m_DownX : point.x,
4950|      m_DownY < point.y ? m_DownY : point.y,
4951|      m_DownX > point.x ? m_DownX : point.x,
4952|      m_DownY > point.y ? m_DownY : point.y );
4953|
4954|    m_HoldPrim = NULL;
4955|    for ( ListX_forEach( &app->m_file.m_prims, &p, ListX_ElemX ) ) {
4956|      if ( ((CadPrim*)p->p)->IsMultiSelect( &rc ) ) {
4957|
4958|        for ( ListX_forEach( &m_MultiHolds, &p2, ListX_ElemX ) ) {
4959|          if ( p2->p == p->p )  break;
4960|        }
4961|        if ( p2 == NULL ) {
4962|          p2 = ListX_addLastMalloc( &m_MultiHolds, ListX_ElemX );
4963|          p2->p = p->p;
4964|          ((CadPrim*)p->p)->SetHold( true );
4965|
4966|          m_HoldPrim = (CadPrim*)p->p;
4967|        }
4968|        else {
4969|          ListX_removeFree( &m_MultiHolds, p2 );
4970|          ((CadPrim*)p->p)->SetHold( false );
4971|        }
4972|      }
4973|    }
4974|    for ( p = ListX_getFirst( &m_MultiHolds, ListX_ElemX ); p != NULL; ) {
4975|      if ( ! ((CadPrim*)p->p)->IsHoldable() ) {
4976|        ((CadPrim*)p->p)->SetHold( false );
4977|        p2 = ListX_Elem_getNextT( p, ListX_ElemX );
4978|        if ( p->p == m_HoldPrim )  m_HoldPrim = NULL;
4979|        ListX_removeFree( &m_MultiHolds, p );
4980|        p = p2;
4981|      }
4982|      else
4983|        p = ListX_Elem_getNextT( p, ListX_ElemX );
4984|    }
4985|    if ( m_HoldPrim == NULL ) {
4986|      p2 = ListX_getFirst( &m_MultiHolds, ListX_ElemX );
4987|      m_HoldPrim = (CadPrim*)( p2 == NULL  ?  NULL : p2->p );
4988|    }
4989|    SetMultiSelect();
4990|
4991|
4992|    /* インクを矩形で選択する */
4993|    if ( m_InkOverlay != NULL ) {
4994|      HRESULT  hr;
4995|      IInkDisp*  ink;
4996|      IInkRectangle*  rect;
4997|      RECT rectX;
4998|      IInkRenderer* render;
4999|      CClientDC  dc( this );
5000|      POINT  pt;
5001|      long  n;
5002|
5003|      hr = m_InkOverlay->get_Renderer( &render );
5004|      if ( hr != 0 ) error();
5005|      hr = m_InkOverlay->get_Ink( &ink );
5006|      if ( hr != 0 )  error();
5007|
5008|      rectX.left = rc.x;  rectX.top = rc.y;
5009|      rectX.right = rc.x + rc.w;  rectX.bottom = rc.y + rc.h;
5010|
5011|      pt = GetScrollPosition();
5012|      rectX.left = rectX.left * m_Zoom / 100;  rectX.right = rectX.right * m_Zoom / 100;
5013|      rectX.top = rectX.top * m_Zoom / 100;    rectX.bottom = rectX.bottom * m_Zoom / 100;
5014|      rectX.left -= pt.x;  rectX.right -= pt.x;
5015|      rectX.top -= pt.y;  rectX.bottom -= pt.y;
5016|      if ( rectX.left == rectX.right )  rectX.right++;  // HitTestWithRectangle 対策
5017|      if ( rectX.top == rectX.bottom )  rectX.bottom++; // HitTestWithRectangle 対策
5018|
5019|      hr = CoCreateInstance( CLSID_InkRectangle, NULL, CLSCTX_INPROC_SERVER,
5020|                             IID_IInkRectangle, (void**)&rect );
5021|      if ( hr != 0 )  error();
5022|      hr = render->PixelToInkSpace( (long)dc.m_hDC, &rectX.left, &rectX.top );
5023|      if ( hr != 0 )  error();
5024|      hr = render->PixelToInkSpace( (long)dc.m_hDC, &rectX.right, &rectX.bottom );
5025|      if ( hr != 0 )  error();
5026|      hr = rect->put_Data( rectX );
5027|      if ( hr != 0 )  error();
5028|
5029|      if ( m_HoldStrokes != NULL )  { hr = m_HoldStrokes->Release();  m_HoldStrokes = NULL; }
5030|      hr = ink->HitTestWithRectangle( rect, 0.0f, &m_HoldStrokes );
5031|      if ( hr != 0 )  error();
5032|      hr = m_InkOverlay->put_Selection( m_HoldStrokes );
5033|      if ( hr != 0 )  error();
5034|
5035|      hr = m_HoldStrokes->get_Count( &n );
5036|      if ( hr != 0 )  error();
5037|
5038|      if ( n == 0 ) { m_HoldStrokes->Release();  m_HoldStrokes = NULL; }
5039|
5040|      hr = rect->Release();  rect = NULL;
5041|      hr = ink->Release();  ink = NULL;
5042|      hr = render->Release();  render = NULL;
5043|
5044|      if ( m_HoldStrokes != NULL )  SetResizeHandle();
5045|
5046|      m_bDrag = FALSE;  /* インクの選択状態を表示するため */
5047|    }
5048|
5049|    Redraw( false );
5050|    frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
5051|  }
5052|  else if ( m_iHoldHandle == -2 ) {
5053|    m_bDrag = FALSE;  /* インクの選択状態を表示するため */
5054|    Redraw( false );
5055|  }
5056|  else if ( m_iHoldHandle == -3 ) {
5057|    HRESULT  hr;
5058|
5059|    if ( m_HoldStrokes != NULL )  { m_HoldStrokes->Release();  m_HoldStrokes = NULL; }
5060|    hr = m_InkOverlay->get_Selection( &m_HoldStrokes );
5061|    if ( hr != 0 )  error();
5062|
5063|    SetResizeHandle();
5064|
5065|    m_bDrag = FALSE;  /* インクの選択状態を表示するため */
5066|    Redraw( false );
5067|  }
5068|}
5069|
5070| 
5071|void  CChildView::OnLButtonUp_DblDlagPrim(UINT nFlags, CPoint point) 
5072|{
5073|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
5074|  CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
5075|  bool  bShift = ( nFlags & MK_SHIFT ) != 0;
5076|
5077|  switch ( m_HoldPrim->GetTypeID() ) {
5078|
5079|   /* Text_Box をダブルクリックしたとき */
5080|   case  Text_Box_TypeID: {
5081|    Text_Box*  prim = (Text_Box*)m_HoldPrim;
5082|    ListX_ElemX*  p;
5083|    CadPrim_DrawParam  pa;
5084|    const char*  str = prim->m_Text;
5085|    char*  str2;
5086|    int  pos;
5087|
5088|   if ( 0 && m_InkOverlay != NULL ) {
5089|
5090|    CInputML  dlg;
5091|
5092|    CWaitCursor wa;
5093|
5094|    GetDrawParam( &pa );
5095|    pos = prim->GetClickedPos( point.x, point.y, &pa );
5096|    dlg.m_iStart = pos;
5097|    str2 = StrX_refTopOfLine( str, StrX_getILine( str, str + pos ) + 1 );
5098|    if ( str2 == NULL )  dlg.m_iEnd = -1;
5099|    else  dlg.m_iEnd = str2 - str - 2;
5100|    dlg.m_iLine = StrX_getILine( prim->m_Text, (const char*)prim->m_Text + pos );
5101|    if ( dlg.m_iLine > 1 )  dlg.m_iLine--;
5102|    dlg.m_bNoSelect = true;
5103|
5104|    dlg.m_ID = (void*)prim->GetID();
5105|    dlg.m_Text = prim->m_Text;
5106|    dlg.m_PenInputPanel = m_PenInputPanel;
5107|    dlg.m_bDispPenPanel = m_bInputML_bDispPenPanel;
5108|    dlg.m_CursorPos = m_DownS;   dlg.m_CursorPos -= GetScrollPosition();
5109|    ClientToScreen( &dlg.m_CursorPos );
5110|    dlg.m_SaveObj = this;  dlg.m_SaveFunc = (CInputML_SaveF)CChildView_saveOnEditing;
5111|    dlg.m_bCtrlRet = app->m_bCtrlRet;
5112|    dlg.m_bJapanese = app->m_bJapanese;
5113|    dlg.m_bHideMain = app->m_bHideMain;
5114|    dlg.m_HideTarget = frame;
5115|    dlg.m_ShowWindowFunc = (CInputML_ShowWindowF)CMainFrame_ShowWindowFunc;
5116|    dlg.m_kword = frame->m_KWord;
5117|    m_InputML = &dlg;
5118|    if ( dlg.DoModal() == IDOK ) {
5119|      if ( ! m_bCreate ) {
5120|        m_BeforePrim = prim->GetNewCopy( &app->m_file.m_prims );
5121|        m_BeforePrim->SetBInUndoBuf( true );
5122|        p = ListX_addLastMalloc( &m_MultiBefore, ListX_ElemX );
5123|        p->p = (void*)prim->GetNewCopy( &app->m_file.m_prims );
5124|        ((CadPrim*)p->p)->SetBInUndoBuf( true );
5125|      }
5126|    }
5127|    else {
5128|      if ( m_bCreate ) {
5129|        app->RemovePrim( &app->m_file, m_HoldPrim );
5130|        m_HoldPrim = NULL;
5131|        m_DragPrim = NULL;
5132|        m_iHoldHandle = 0;
5133|        ListX_toEmptyDelete( &m_MultiHolds, ListX_ElemX, NULL );
5134|        m_bCreate = FALSE;
5135|        m_bDrag = FALSE;
5136|        Redraw( false );
5137|        frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
5138|      }
5139|      SetMultiSelect();
5140|    }
5141|    m_InputML = NULL;
5142|    app->m_bCtrlRet = dlg.m_bCtrlRet;
5143|    app->m_bHideMain = dlg.m_bHideMain;
5144|    frame->m_KWord = dlg.m_kword;
5145|    prim->m_Text = dlg.m_Text;
5146|    Redraw( false );
5147|    prim->Move( 0, 0 );  /* リンクラインを調節する */
5148|    frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
5149|    m_bInputML_bDispPenPanel = dlg.m_bDispPenPanel;
5150|   }
5151|   else {
5152|    CInputML1  dlg;
5153|
5154|    CWaitCursor wa;
5155|
5156|    GetDrawParam( &pa );
5157|    pos = prim->GetClickedPos( point.x, point.y, &pa );
5158|    dlg.m_iStart = pos;
5159|    str2 = StrX_refTopOfLine( str, StrX_getILine( str, str + pos ) + 1 );
5160|    if ( str2 == NULL )  dlg.m_iEnd = -1;
5161|    else  dlg.m_iEnd = str2 - str - 2;
5162|    dlg.m_iLine = StrX_getILine( prim->m_Text, (const char*)prim->m_Text + pos );
5163|    if ( dlg.m_iLine > 1 )  dlg.m_iLine--;
5164|    dlg.m_bNoSelect = true;
5165|
5166|    dlg.m_ID = (void*)prim->GetID();
5167|    dlg.m_Text = prim->m_Text;
5168|    dlg.m_PenInputPanel = m_PenInputPanel;
5169|    dlg.m_bDispPenPanel = m_bInputML_bDispPenPanel;
5170|    dlg.m_CursorPos = m_DownS;   dlg.m_CursorPos -= GetScrollPosition();
5171|    ClientToScreen( &dlg.m_CursorPos );
5172|    dlg.m_SaveObj = this;  dlg.m_SaveFunc = (CInputML1_SaveF)CChildView_saveOnEditing1;
5173|    dlg.m_bCtrlRet = app->m_bCtrlRet;
5174|    dlg.m_bJapanese = app->m_bJapanese;
5175|    dlg.m_bHideMain = app->m_bHideMain;
5176|    dlg.m_HideTarget = frame;
5177|    dlg.m_ShowWindowFunc = (CInputML1_ShowWindowF)CMainFrame_ShowWindowFunc;
5178|    dlg.m_kword = frame->m_KWord;
5179|    m_InputML1 = &dlg;
5180|//setWATCH( &((*(CadPrim*)(&*prim))).__vfptr, 4, 0 );
5181|
5182|    if ( dlg.DoModal() == IDOK ) {
5183|      if ( ! m_bCreate ) {
5184|        m_BeforePrim = prim->GetNewCopy( &app->m_file.m_prims );
5185|        m_BeforePrim->SetBInUndoBuf( true );
5186|        p = ListX_addLastMalloc( &m_MultiBefore, ListX_ElemX );
5187|        p->p = (void*)prim->GetNewCopy( &app->m_file.m_prims );
5188|        ((CadPrim*)p->p)->SetBInUndoBuf( true );
5189|      }
5190|    }
5191|    else {
5192|      if ( m_bCreate ) {
5193|        app->RemovePrim( &app->m_file, m_HoldPrim );
5194|        m_HoldPrim = NULL;
5195|        m_DragPrim = NULL;
5196|        m_iHoldHandle = 0;
5197|        ListX_toEmptyDelete( &m_MultiHolds, ListX_ElemX, NULL );
5198|        m_bCreate = FALSE;
5199|        m_bDrag = FALSE;
5200|        Redraw( false );
5201|        frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
5202|      }
5203|      SetMultiSelect();
5204|    }
5205|    m_InputML1 = NULL;
5206|    app->m_bCtrlRet = dlg.m_bCtrlRet;
5207|    app->m_bHideMain = dlg.m_bHideMain;
5208|    frame->m_KWord = dlg.m_kword;
5209|    prim->m_Text = dlg.m_Text;
5210|    Redraw( false );
5211|    prim->Move( 0, 0 );  /* リンクラインを調節する */
5212|    frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
5213|    m_bInputML_bDispPenPanel = dlg.m_bDispPenPanel;
5214|   }
5215|   }
5216|    break;
5217|
5218|   case  Line_Ex_TypeID:
5219|   case  Line_Corner_TypeID: {
5220|
5221|    /* ダブルクリックしたとき */
5222|    if ( m_HoldPrim == m_DragPrim ) {
5223|      if ( m_DragPrim->GetTypeID() == Line_Corner_TypeID ) {
5224|        ((Line_Corner*)m_HoldPrim)->m_Dir = ! ((Line_Corner*)m_HoldPrim)->m_Dir;
5225|        Redraw( false );
5226|        frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
5227|      }
5228|    }
5229|
5230|    /* ダブルクリック・ドラッグで終点が決定したとき */
5231|    else if ( m_DragPrim != NULL ) {
5232|      Text_Box*  text;
5233|      CadPrim*   linkPrim = NULL;
5234|      int  dx = point.x - m_DownX;
5235|      int  dy = point.y - m_DownY;
5236|      ListX_ElemX*  p;
5237|      int  diff, arrow;
5238|
5239|      if ( m_HoldPrim->GetTypeID() == Line_Corner_TypeID )
5240|        ((Line_Corner*)m_HoldPrim)->m_SlideCorner = false;
5241|
5242|      if ( dx > -16 && dx < 16 )  point.x = m_DownX;
5243|      if ( dy > -16 && dy < 16 )  point.y = m_DownY;
5244|
5245|      for ( ListX_forEach( &app->m_file.m_prims, &p, ListX_ElemX ) ) {
5246|        if ( (CadPrim*)p->p == m_DragPrim )  continue;
5247|        if ( ((CadPrim*)p->p)->GetHitHandleNum( point.x, point.y, m_Zoom,
5248|              CadPrim_ResizeMode, &dx, &dy, &diff, &arrow ) != 0 ) {
5249|          if ( ((CadPrim*)p->p)->GetTypeID() == Text_Box_TypeID )
5250|            break;
5251|        }
5252|      }
5253|
5254|      /* 終点が枠付きテキストではないときは、新たに枠付きテキストを生成する */
5255|      if ( p == NULL ) {
5256|        if ( m_DragPrim->GetHitHandleNum( point.x, point.y, m_Zoom,
5257|             CadPrim_ResizeMode, &dx, &dy, &diff, &arrow ) != 0 ) {
5258|          text = NULL;  /* 自分自身のとき */
5259|        }
5260|        else {
5261|          Line_Corner*  line = (Line_Corner*)m_HoldPrim;
5262|
5263|          text = new Text_Box;
5264|          text->copy( m_DragPrim, &app->m_file.m_prims );
5265|          text->m_id = app->GetNewPrimID();
5266|          text->m_Text = CString("ABC");
5267|          text->m_CenterX = line->m_Line.x2;
5268|          if ( line->m_Line.y1 == line->m_Line.y2 )
5269|            text->m_Y = ((Text_Box*)m_DragPrim)->m_Y;
5270|          else
5271|            text->m_Y = line->m_Line.y2;
5272|          text->m_W = 100;  text->m_10H = 320;
5273|          if ( text->m_BoxShape == Text_Box_DiamondShape )
5274|            text->ChangeShape( Text_Box_RectShape );
5275|          ListX_toEmptyDelete( &text->m_Links, ListX_ElemX, NULL );
5276|          text->m_Controler = NULL;
5277|          text->m_Controler_id = 0;
5278|
5279|          app->AddPrim( &app->m_file, text );
5280|        }
5281|      }
5282|      else {
5283|        text = (Text_Box*)p->p;
5284|        text->ChangeAlign( Text_Box_CenterAlign );
5285|        if ( text->m_BoxShape == Text_Box_NoFrame ) {
5286|          text->m_BoxShape = Text_Box_RectShape;
5287|          text->m_BorderWidth = 0;
5288|        }
5289|        linkPrim = text->GetNewCopy( &app->m_file.m_prims );
5290|      }
5291|
5292|      if ( text == NULL ) {
5293|        m_HoldPrim->UnlinkAll();  /* m_HoldPrim == line */
5294|        app->RemovePrim( &app->m_file, m_HoldPrim );
5295|        m_HoldPrim = NULL;
5296|        m_DragPrim->copy( m_BeforePrim, &app->m_file.m_prims );  /* m_DragPrim == base text */
5297|        delete  m_BeforePrim;  m_BeforePrim = NULL;
5298|        Redraw( false );
5299|        frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
5300|      }
5301|      else {
5302|        CadPrim_DrawParam  pa;
5303|
5304|        GetDrawParam( &pa );
5305|        Redraw( false );  /* リンクラインは、描画後に座標が決定するため */
5306|
5307|        /* text をラインとリンクする */
5308|        text->LinkToHandle( 0, m_HoldPrim, 2 );
5309|        text->Draw( &m_BitmapDC, &pa );  /* テキストの中心を計算する */
5310|        text->MoveLinks( true );
5311|
5312|
5313|        /* 新たに生成したときは、テキスト入力ダイアログを表示する */
5314|        if ( p == NULL ) {
5315|         if ( 0 && m_InkOverlay != NULL ) {
5316|          CInputML  dlg;
5317|          CadPrim*  hold;
5318|
5319|          dlg.m_ID = (void*)text->GetID();
5320|          dlg.m_Text = text->m_Text;
5321|          dlg.m_PenInputPanel = m_PenInputPanel;
5322|          dlg.m_bDispPenPanel = m_bInputML_bDispPenPanel;
5323|          dlg.m_CursorPos = m_UpS;
5324|          dlg.m_SaveObj = this;  dlg.m_SaveFunc = (CInputML_SaveF)CChildView_saveOnEditing;
5325|          dlg.m_bCtrlRet = app->m_bCtrlRet;
5326|          dlg.m_bJapanese = app->m_bJapanese;
5327|          dlg.m_bHideMain = app->m_bHideMain;
5328|          dlg.m_HideTarget = frame;
5329|          dlg.m_ShowWindowFunc = (CInputML_ShowWindowF)CMainFrame_ShowWindowFunc;
5330|          dlg.m_kword = frame->m_KWord;
5331|          Redraw( false );
5332|          m_InputML = &dlg;
5333|          hold = m_HoldPrim;  m_HoldPrim = text;
5334|          if ( dlg.DoModal() == IDOK ) {
5335|            m_InputML = NULL;
5336|            text->m_Text = dlg.m_Text;
5337|            text->Draw( &m_BitmapDC, &pa );  /* 矢印の先端の座標を計算しておく */
5338|          }
5339|          else {
5340|            m_InputML = NULL;
5341|            text->UnlinkAll();
5342|            app->RemovePrim( &app->m_file, text );
5343|            text = NULL;
5344|          }
5345|          m_HoldPrim = hold;
5346|          m_bInputML_bDispPenPanel = dlg.m_bDispPenPanel;
5347|          app->m_bCtrlRet = dlg.m_bCtrlRet;
5348|          app->m_bHideMain = dlg.m_bHideMain;
5349|          frame->m_KWord = dlg.m_kword;
5350|         }
5351|         else {
5352|          CInputML1  dlg;
5353|          CadPrim*  hold;
5354|
5355|          dlg.m_ID = (void*)text->GetID();
5356|          dlg.m_Text = text->m_Text;
5357|          dlg.m_PenInputPanel = m_PenInputPanel;
5358|          dlg.m_bDispPenPanel = m_bInputML_bDispPenPanel;
5359|          dlg.m_CursorPos = m_UpS;
5360|          dlg.m_SaveObj = this;  dlg.m_SaveFunc = (CInputML1_SaveF)CChildView_saveOnEditing1;
5361|          dlg.m_bCtrlRet = app->m_bCtrlRet;
5362|          dlg.m_bJapanese = app->m_bJapanese;
5363|          dlg.m_bHideMain = app->m_bHideMain;
5364|          dlg.m_HideTarget = frame;
5365|          dlg.m_ShowWindowFunc = (CInputML1_ShowWindowF)CMainFrame_ShowWindowFunc;
5366|          dlg.m_kword = frame->m_KWord;
5367|          Redraw( false );
5368|          m_InputML1 = &dlg;
5369|          hold = m_HoldPrim;  m_HoldPrim = text;
5370|          if ( dlg.DoModal() == IDOK ) {
5371|            m_InputML1 = NULL;
5372|            text->m_Text = dlg.m_Text;
5373|            text->Draw( &m_BitmapDC, &pa );  /* 矢印の先端の座標を計算しておく */
5374|          }
5375|          else {
5376|            m_InputML1 = NULL;
5377|            text->UnlinkAll();
5378|            app->RemovePrim( &app->m_file, text );
5379|            text = NULL;
5380|          }
5381|          m_HoldPrim = hold;
5382|          m_bInputML_bDispPenPanel = dlg.m_bDispPenPanel;
5383|          app->m_bCtrlRet = dlg.m_bCtrlRet;
5384|          app->m_bHideMain = dlg.m_bHideMain;
5385|          frame->m_KWord = dlg.m_kword;
5386|         }
5387|        }
5388|
5389|        /* アンドゥバッファに記録する */
5390|        app->m_UndoBuf->StartMulti();
5391|
5392|        app->m_UndoBuf->AllocNewStep( m_BeforePrim, m_DragPrim->GetNewCopy( &app->m_file.m_prims ),
5393|          NULL, NULL, app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
5394|
5395|        for ( ListX_forEach( &app->m_file.m_prims, &p, ListX_ElemX ) ) {
5396|          if ( (CadPrim*)p->p == m_HoldPrim )  break;
5397|        }
5398|        ASSERT( p != NULL );
5399|        p = ListX_Elem_getNextT( p, ListX_ElemX );
5400|        app->m_UndoBuf->AllocNewStep( NULL, m_HoldPrim->GetNewCopy( &app->m_file.m_prims ),
5401|          NULL, p == NULL ? NULL : ((CadPrim*)p->p)->GetNewCopy( &app->m_file.m_prims ),
5402|          app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
5403|
5404|        if ( text != NULL ) {
5405|          if ( linkPrim == NULL ) {
5406|            for ( ListX_forEach( &app->m_file.m_prims, &p, ListX_ElemX ) ) {
5407|              if ( (CadPrim*)p->p == text )  break;
5408|            }
5409|            ASSERT( p != NULL );
5410|            p = ListX_Elem_getNextT( p, ListX_ElemX );
5411|            app->m_UndoBuf->AllocNewStep( NULL, text->GetNewCopy( &app->m_file.m_prims ),
5412|              NULL, p == NULL ? NULL : ((CadPrim*)p->p)->GetNewCopy( &app->m_file.m_prims ),
5413|              app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
5414|          }
5415|          else {
5416|            app->m_UndoBuf->AllocNewStep( linkPrim, text->GetNewCopy( &app->m_file.m_prims ),
5417|              NULL, NULL, app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
5418|          }
5419|        }
5420|
5421|        app->m_UndoBuf->EndMulti();
5422|
5423|        ListX_toEmptyDelete( &m_MultiHolds, ListX_ElemX, NULL );
5424|        m_DragPrim->SetHold( false );
5425|
5426|        if ( text == NULL ) {
5427|          p = ListX_addLastMalloc( &m_MultiHolds, ListX_ElemX );
5428|          p->p = m_HoldPrim;
5429|          SetMultiSelect();
5430|          m_HoldPrim->SetHold( true );
5431|        }
5432|        else {
5433|          p = ListX_addLastMalloc( &m_MultiHolds, ListX_ElemX );
5434|          p->p = text;
5435|          SetMultiSelect();
5436|          m_HoldPrim = text;
5437|          m_HoldPrim->SetHold( true );
5438|        }
5439|
5440|        m_BeforePrim = NULL;
5441|        Redraw( false );
5442|        frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
5443|      }
5444|      for ( ListX_forEach( &m_MultiBefore, &p, ListX_ElemX ) ) {
5445|        delete  (CadPrim*)p->p;
5446|      }
5447|      ListX_toEmptyDelete( &m_MultiBefore, ListX_ElemX, NULL );
5448|    }
5449|    break;
5450|   }
5451|  }
5452|}
5453|
5454|
5455| 
5456|/***********************************************************************
5457|  39. <<< [CChildView::OnMouseMove] >>> 
5458|************************************************************************/
5459|void CChildView::OnMouseMove(UINT nFlags, CPoint point)
5460|{
5461|  POINT  pt;
5462|  CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
5463|
5464|  if ( m_Bitmap == NULL )  return;
5465|
5466|  ERRORS_FUNC_CPP_VAR( CChildView_OnMouseMove );
5467|  ERRORS_FUNC_START_CPP( CChildView_OnMouseMove );
5468|
5469|
5470|  if ( frame->IsPenMode() ) {
5471|    CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
5472|    bool  f = true;
5473|
5474|    /* 行操作は、高速処理の経路を通らない */
5475|    if ( m_bRightDrag ) {
5476|      //CPoint  down;
5477|
5478|      //down = m_DownS;
5479|      //ScreenToClient( &down );
5480|      //down -= GetScrollPosition();
5481|
5482|      f = false;  //! ( down.x > app->m_file.m_Canvas.m_Width );
5483|    }
5484|    /* キャンバスサイズ変更は、高速処理の経路を通らない */
5485|    if ( m_HoldPrim == &app->m_file.m_Canvas ||     /* ←キャンバスサイズを小さくするため */
5486|         point.x > app->m_file.m_Canvas.m_Width ||  /* ←カーソル形状のため */
5487|         point.y > app->m_file.m_Canvas.m_Height ) {
5488|      f = false;
5489|    }
5490|    /* 高速処理の経路 */
5491|    if ( f ) {
5492|      ERRORS_FUNC_END_CPP( CChildView_OnMouseMove );
5493|      return;
5494|    }
5495|  }
5496|
5497|  if ( frame->m_bScopeMode ) {
5498|    frame->m_bScopeHiding = true;
5499|  }
5500|
5501|  pt = GetScrollPosition();
5502|  point += pt;
5503|  point -= m_MinusOffset;
5504|  point.x = point.x * 100 / m_Zoom;
5505|  point.y = point.y * 100 / m_Zoom;
5506|
5507|  ASSERT( ! ( m_bDrag && m_bDblDrag ) );
5508|
5509|  #ifdef  USES_INK
5510|  if ( frame->IsPenMode() && m_iHoldHandle != 2 ) {
5511|    /* ストレッチ */
5512|    if ( m_HoldInk != NULL ) {
5513|      CClientDC  dc( this );
5514|      CRgn  clip;
5515|      RECT  rc;
5516|      CadPrim_DrawParam  p;
5517|
5518|      GetDrawParam( &p );
5519|      GetClientRect( &rc );
5520|      clip.CreateRectRgn( 0,  0,  rc.right,  rc.bottom );
5521|      dc.SelectClipRgn( &clip );
5522|
5523|      m_HoldInk->Scratch( &dc, &p, point.x, point.y );
5524|    }
5525|    ERRORS_FUNC_END_CPP( CChildView_OnMouseMove );
5526|    return;
5527|  }
5528|  #endif
5529|
5530|  if ( m_bDrag ) {
5531|    long dx;
5532|    long dy;
5533|    bool  bShift = ( nFlags & MK_SHIFT ) != 0;
5534|    bool  bCtrl = ( nFlags & MK_CONTROL ) != 0;
5535|    int  diff = 4;
5536|
5537|    dx = point.x - m_DownX;
5538|    dy = point.y - m_DownY;
5539|    diff = diff * 100 / m_Zoom;  if ( diff < 1 )  diff = 1;
5540|
5541|    /* 図形選択モードに移る */
5542|    if ( ! m_bCreate && frame->m_mode != CMainFrame_Select
5543|          && frame->m_mode != CMainFrame_Rotate && frame->IsPenMode()
5544|          && ! frame->IsPenMode() ) {
5545|      frame->m_mode = CMainFrame_Select;
5546|      frame->UpdateCreateToolBar( ID_Select, &frame->m_CreateBar, true );
5547|    }
5548|
5549|    /* 複数選択用の矩形を描画する */
5550|    if ( m_HoldPrim == NULL && m_iHoldHandle == 2 ) {
5551|      CClientDC  dc(this);
5552|
5553|      Redraw( false );
5554|      RedrawWidthArea( &dc, m_DownX, m_DownY, point.x, point.y );
5555|    }
5556|
5557|
5558|    /* 複数の図形を同時に移動する */
5559|    if ( ( m_iHoldHandle == -2 || ( m_HoldStrokes != NULL && m_iHoldHandle != -3 ) )
5560|        && ( ! m_bInDragPlay || dx < -diff || dx > diff || dy < -diff || dy > diff ) ) {
5561|      ListX_ElemX*  p;
5562|      CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
5563|      int  x1, y1, x2, y2;
5564|
5565|      if ( ! app->m_file.m_Canvas.m_bGridOn )  SetCursor( NULL );
5566|
5567|      AutoAdjustXY( &point.x, &point.y, false, bCtrl );
5568|      dx = point.x - m_DownX;
5569|      dy = point.y - m_DownY;
5570|
5571|      if ( app->m_file.m_Canvas.m_bGridOn ) {
5572|
5573|        /* 前回、図形の基準点がグリッドされたアドレスを x1, y1 に取得する */
5574|        if ( ! m_bDragGrided && m_HoldPrim->GetTypeID() == Text_Box_TypeID )
5575|          m_Hold_dy += Text_Box_GridGap;
5576|        x1 = m_DownX + m_Hold_dx;   y1 = m_DownY + m_Hold_dy;
5577|        if ( m_bDragGrided )  app->m_file.m_Canvas.ChgToGridedPos( &x1, &y1 );
5578|
5579|        /* 今回、図形の基準点がグリッドされたアドレスを x2, y2 に取得する */
5580|        x2 = point.x + m_Hold_dx;   y2 = point.y + m_Hold_dy;
5581|        app->m_file.m_Canvas.ChgToGridedPos( &x2, &y2 );
5582|
5583|        dx = x2 - x1;
5584|        dy = y2 - y1;
5585|        m_bDragGrided = TRUE;
5586|      }
5587|      m_DownX = point.x;  m_DownY = point.y;
5588|
5589|      if ( m_iHoldHandle == -2 ) {
5590|        for ( ListX_forEach( &m_MultiSelects, &p, ListX_ElemX ) ) {
5591|          ((CadPrim*)p->p)->Move( dx, dy );
5592|        }
5593|        /* 移動した後で、リンクラインのずれをなくす */
5594|        for ( ListX_forEach( &m_MultiSelects, &p, ListX_ElemX ) ) {
5595|          ((CadPrim*)p->p)->Move( 0, 0 );
5596|        }
5597|        m_bInDragPlay = FALSE;
5598|      }
5599|
5600|      /* インクを移動する */
5601|      if ( m_HoldStrokes != NULL && ( dx != 0 || dy != 0 ) ) {
5602|        HRESULT  hr;
5603|        IInkRenderer* render;
5604|        long  dx0 = 0,  dy0 = 0;
5605|        CClientDC  dc( this );
5606|
5607|        hr = m_InkOverlay->get_Renderer( &render );
5608|        if ( hr != 0 ) error();
5609|        hr = render->PixelToInkSpace( (long)dc.m_hDC, &dx0, &dy0 );
5610|        if ( hr != 0 )  error();
5611|        hr = render->PixelToInkSpace( (long)dc.m_hDC, &dx, &dy );
5612|        if ( hr != 0 )  error();
5613|
5614|        hr = m_HoldStrokes->Move( (float)( (dx - dx0) * m_Zoom / 100 ),
5615|                                  (float)( (dy - dy0) * m_Zoom / 100 ) );
5616|        if ( hr != 0 ) error();
5617|
5618|        hr = render->Release();  render = NULL;
5619|
5620|        SetResizeHandle();
5621|      }
5622|
5623|      Redraw( false );
5624|      StartCountForDragScroll();
5625|    }
5626|
5627|    /* 1つの図形を移動または修正する */
5628|    if ( m_iHoldHandle != -2 && ( ! m_bInDragPlay || dx < -diff || dx > diff || dy < -diff || dy > diff ) ) {
5629|
5630|      CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
5631|      int  x, y;
5632|
5633|      if ( m_SingleDblClickTimer != 0 )  frame->KillTimer( m_SingleDblClickTimer );
5634|      m_SingleDblClickTimer = 0;
5635|
5636|      if ( frame->m_mode != CMainFrame_Rotate &&  ! app->m_file.m_Canvas.m_bGridOn )
5637|        SetCursor( NULL );
5638|
5639|      /* キャンバスのサイズを変更する */
5640|      if ( m_HoldPrim == NULL );
5641|      else if ( m_HoldPrim == &app->m_file.m_Canvas ) {
5642|        HRESULT  hr;
5643|
5644|        app->m_file.m_Canvas.m_Width = point.x - 2;
5645|        if ( app->m_file.m_Canvas.m_Width < 1 )  app->m_file.m_Canvas.m_Width = 1;
5646|        app->m_file.m_Canvas.m_Height = point.y - 2;
5647|        if ( app->m_file.m_Canvas.m_Height < 1 )  app->m_file.m_Canvas.m_Height = 1;
5648|        frame->ResetProp();
5649|        m_bBitmap = false;
5650|        m_bInDragPlay = FALSE;
5651|
5652|        if ( m_InkOverlay != NULL ) {
5653|          hr = m_InkRectangle->SetRectangle( /*top*/ 0, /*left*/ 0,
5654|            /*bottom*/ app->m_file.m_Canvas.m_Height * m_Zoom / 100, /*right*/ app->m_file.m_Canvas.m_Width * m_Zoom / 100 );
5655|          if ( hr != 0 )  error();
5656|
5657|          m_InkOverlay->SetWindowInputRectangle( m_InkRectangle );
5658|          if ( hr != 0 )  error();
5659|        }
5660|
5661|        Invalidate( FALSE );
5662|      }
5663|
5664|      /* 図形を変更または移動する */
5665|      else {
5666|        x = point.x + m_Hold_dx;   y = point.y + m_Hold_dy;
5667|        app->m_file.m_Canvas.ChgToGridedPos( &x, &y );
5668|        if ( app->m_file.m_Canvas.m_bGridOn &&
5669|             m_HoldPrim->GetTypeID() == Text_Box_TypeID && m_iHoldHandle < 0 ) {
5670|          y -= Text_Box_GridGap;
5671|        }
5672|        AutoAdjustXY( (long*)&x, (long*)&y, m_iHoldHandle >= 1 && ! bShift, bCtrl );
5673|        m_HoldPrim->MoveByHandle( m_iHoldHandle, x, y, bShift,
5674|          frame->m_mode == CMainFrame_Rotate );
5675|        m_bInDragPlay = FALSE;
5676|        Redraw( false );
5677|        #if 0
5678|        {  /* 移動中のハンドルを表示する */
5679|          CClientDC  dc(this);
5680|          CadPrim_DrawParam  p;
5681|
5682|          GetDrawParam( &p );
5683|          m_HoldPrim->DrawHandles( &dc, &p, GetSysColor( COLOR_HIGHLIGHT ), true );
5684|        }
5685|        #endif
5686|        frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
5687|        m_DownX = point.x;  m_DownY = point.y;
5688|      }
5689|      StartCountForDragScroll();
5690|    }
5691|
5692|    /* 書かれているインクの大きさを変える。リサイズ */
5693|    if ( m_iHoldHandle == -3 ) {
5694|      HRESULT  hr;
5695|      IInkRenderer* render;
5696|      IInkRectangle*  rect;
5697|      IInkStrokes*  strokes;
5698|      RECT rectX;
5699|      CClientDC  dc( this );
5700|
5701|      hr = m_InkOverlay->get_Renderer( &render );  if ( hr != 0 ) error();
5702|      hr = m_InkOverlay->get_Selection( &strokes );  if ( hr != 0 ) error();
5703|      hr = strokes->GetBoundingBox( IBBM_Default, &rect );  if ( hr != 0 )  error();
5704|      hr = rect->get_Data( &rectX );  if ( hr != 0 )  error();
5705|
5706|      rectX.right = point.x * m_Zoom / 100 - 4 - pt.x;
5707|      rectX.bottom = point.y * m_Zoom / 100 - 4 - pt.y;
5708|      hr = render->PixelToInkSpace( (long)dc.m_hDC, &rectX.right, &rectX.bottom );
5709|      if ( hr != 0 )  error();
5710|      if ( rectX.right < rectX.left + 100 )  rectX.right = rectX.left + 100;
5711|      if ( rectX.bottom < rectX.top + 100 )  rectX.bottom = rectX.top + 100;
5712|      hr = rect->put_Data( rectX );  if ( hr != 0 )  error();
5713|
5714|      hr = strokes->ScaleToRectangle( rect );
5715|      if ( hr != 0 )  error();
5716|
5717|      hr = rect->Release();  rect = NULL;
5718|      hr = strokes->Release();  strokes = NULL;
5719|      hr = render->Release();  render = NULL;
5720|
5721|      Redraw( false );
5722|    }
5723|  }
5724|
5725|  else if ( m_bDblDrag ) {
5726|    int  dx = point.x - m_DownX;
5727|    int  dy = point.y - m_DownY;
5728|    bool  bShift = ( nFlags & MK_SHIFT ) != 0;
5729|    bool  bCtrl = ( nFlags & MK_CONTROL ) != 0;
5730|    enum { diff = 30 };
5731|
5732|    if ( ! m_bInDragPlay || dx < -diff || dx > diff || dy < -diff || dy > diff ) {
5733|
5734|      CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
5735|
5736|      if ( m_SingleDblClickTimer != 0 )  frame->KillTimer( m_SingleDblClickTimer );
5737|      m_SingleDblClickTimer = 0;
5738|      m_bInDragPlay = false;
5739|
5740|      SetCursor( NULL );
5741|
5742|      if ( dx > -16 && dx < 16 )  point.x = m_DownX;
5743|      if ( dy > -16 && dy < 16 )  point.y = m_DownY;
5744|
5745|      /* 枠付きテキストからダブルクリックドラッグを開始する */
5746|      if ( m_HoldPrim->GetTypeID() == Text_Box_TypeID && ! m_bCreate ) {
5747|        Text_Box*  text = (Text_Box*)m_HoldPrim;
5748|        ListX_ElemX*  p;
5749|
5750|        ASSERT( m_BeforePrim == NULL );
5751|        ASSERT( ListX_isEmpty( &m_MultiBefore ) );
5752|        m_BeforePrim = m_HoldPrim->GetNewCopy( &app->m_file.m_prims );
5753|        m_BeforePrim->SetBInUndoBuf( true );
5754|        p = ListX_addFirstMalloc( &m_MultiBefore, ListX_ElemX );
5755|        p->p = m_HoldPrim->GetNewCopy( &app->m_file.m_prims );
5756|        ((CadPrim*)p->p)->SetBInUndoBuf( true );
5757|
5758|        text->ChangeAlign( Text_Box_CenterAlign );
5759|        if ( ( text->m_BoxShape == Text_Box_NoFrame && ! m_bCreate ) ||
5760|             ( text->m_BoxShape == Text_Box_RectShape &&
5761|               text->m_BorderWidth == 0 &&
5762|               text->m_BoxMarginX == 2 &&  text->m_BoxMarginY == 2 ) ) {
5763|          text->m_BoxShape = Text_Box_RectShape;
5764|          text->m_BorderWidth = 0;
5765|          text->m_FillColor = RGB(0xFF,0xFF,0xFF);
5766|          text->m_BoxMarginX = 2;  text->m_BoxMarginY = 2;
5767|          bShift = ! bShift;
5768|        }
5769|        else if ( text->m_BoxShape == Text_Box_CircleShape ) {
5770|          bShift = ! bShift;
5771|        }
5772|
5773|        if ( bShift ) {
5774|          Line_Ex*  line;
5775|
5776|          if ( frame->m_ArrowDesign != NULL ) {
5777|            line = (Line_Ex*)frame->m_ArrowDesign->GetNewCopy( &app->m_file.m_prims );
5778|            line->m_id = app->GetNewPrimID();
5779|            Line_init( &line->m_Line, m_DownX, m_DownY, m_DownX, m_DownY );
5780|          }
5781|          else {
5782|            line = new Line_Ex;
5783|            line->m_id = app->GetNewPrimID();
5784|            Line_init( &line->m_Line, m_DownX, m_DownY, m_DownX, m_DownY );
5785|            line->m_Width = 1;
5786|            line->m_Color = 0;
5787|          }
5788|          line->m_Arrow2 = ( bCtrl ? 0 : 1 );
5789|
5790|          app->AddPrimToBottomLine( &app->m_file, line );
5791|          m_HoldPrim->LinkToHandle( 0, line, 1 );
5792|
5793|          m_DragPrim = m_HoldPrim;
5794|          m_HoldPrim = line;
5795|          frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
5796|        }
5797|        else {
5798|          Line_Corner*  line;
5799|
5800|          if ( frame->m_CorneredLineDesign != NULL ) {
5801|            line = (Line_Corner*)frame->m_CorneredLineDesign->GetNewCopy( &app->m_file.m_prims );
5802|            line->m_id = app->GetNewPrimID();
5803|            Line_init( &line->m_Line, m_DownX, m_DownY, m_DownX, m_DownY );
5804|            line->m_CornerX = m_DownX;  line->m_CornerY = m_DownY;
5805|            line->m_Dir = Line_DirN;
5806|          }
5807|          else {
5808|            line = new Line_Corner;
5809|            line->m_id = app->GetNewPrimID();
5810|            Line_init( &line->m_Line, m_DownX, m_DownY, m_DownX, m_DownY );
5811|            line->m_CornerX = m_DownX;  line->m_CornerY = m_DownY;
5812|            line->m_Dir = Line_DirN;
5813|            line->m_SlideCorner = true;
5814|            line->m_Width = 1;
5815|            line->m_Color = 0;
5816|          }
5817|          line->m_Arrow2 = ( bCtrl ? 0 : 1 );
5818|
5819|          app->AddPrimToBottomLine( &app->m_file, line );
5820|          m_HoldPrim->LinkToHandle( 0, line, 1 );
5821|
5822|          m_DragPrim = m_HoldPrim;
5823|          m_HoldPrim = line;
5824|          frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
5825|        }
5826|        m_iHoldHandle = 2;
5827|        m_Hold_dx = 0;  m_Hold_dy = 0;
5828|        SetCapture();
5829|      }
5830|
5831|      /* 何もないところをダブルクリックドラッグしたら矢印を引く */
5832|      if ( m_HoldPrim->GetTypeID() == Text_Box_TypeID && m_bCreate ) {
5833|        Line_Ex*  line;
5834|        ListX_ElemX*  p;
5835|
5836|        m_HoldPrim->UnlinkAll();
5837|        app->RemovePrim( &app->m_file, m_HoldPrim );  /* ダブルクリックで生成した text を削除してから */
5838|        delete  m_BeforePrim;  m_BeforePrim = NULL;
5839|        for ( ListX_forEach( &m_MultiBefore, &p, ListX_ElemX ) ) {
5840|          delete  (CadPrim*)p->p;
5841|        }
5842|        ListX_toEmptyDelete( &m_MultiBefore, ListX_ElemX, NULL );
5843|        ListX_toEmptyDelete( &m_MultiHolds, ListX_ElemX, NULL );
5844|
5845|        if ( frame->m_ArrowDesign != NULL ) {
5846|          line = (Line_Ex*)frame->m_ArrowDesign->GetNewCopy( &app->m_file.m_prims );
5847|          line->m_id = app->GetNewPrimID();
5848|          Line_init( &line->m_Line, m_DownX, m_DownY, m_DownX, m_DownY );
5849|          app->m_file.m_Canvas.ChgToGridedPos( &line->m_Line.x1, &line->m_Line.y1 );
5850|          app->m_file.m_Canvas.ChgToGridedPos( &line->m_Line.x2, &line->m_Line.y2 );
5851|        }
5852|        else {
5853|          line = new Line_Ex;
5854|          line->m_id = app->GetNewPrimID();
5855|          Line_init( &line->m_Line, m_DownX, m_DownY, m_DownX, m_DownY );
5856|          app->m_file.m_Canvas.ChgToGridedPos( &line->m_Line.x1, &line->m_Line.y1 );
5857|          app->m_file.m_Canvas.ChgToGridedPos( &line->m_Line.x2, &line->m_Line.y2 );
5858|          line->m_Width = 1;
5859|          line->m_Color = 0;
5860|        }
5861|        line->m_Arrow2 = ( bCtrl ? 0 : 1 );
5862|
5863|        app->AddPrimToBottomLine( &app->m_file, line );
5864|
5865|        m_DragPrim = line;
5866|        m_HoldPrim = line;
5867|        line->SetHold( true );
5868|        m_iHoldHandle = 2;
5869|        p = ListX_addFirstMalloc( &m_MultiHolds, ListX_ElemX );
5870|        p->p = line;
5871|        SetMultiSelect();
5872|        frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
5873|        m_bInDragPlay = FALSE;
5874|        Redraw( false );
5875|      }
5876|
5877|      /* 図形を変更または移動する */
5878|      else {
5879|        int  x, y;
5880|
5881|        x = point.x + m_Hold_dx;  y = point.y + m_Hold_dy;
5882|        app->m_file.m_Canvas.ChgToGridedPos( &x, &y );
5883|        m_HoldPrim->MoveByHandle( m_iHoldHandle, x, y, bShift, false );
5884|        m_bInDragPlay = FALSE;
5885|        Redraw( false );
5886|        frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
5887|      }
5888|    }
5889|  }
5890|  else if ( m_bRightDrag ) {
5891|    CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
5892|    CPoint  down;
5893|
5894|    down = m_DownS;
5895|
5896|    if ( m_HoldPrim == NULL  /* && down.x > app->m_file.m_Canvas.m_Width */ ) {
5897|      int  dy;
5898|      int  y, mostBottomY = 0;
5899|      ListX_ElemX*  p;
5900|      CadPrim*  prim;
5901|
5902|      /* 行を削除する範囲を0に縮める */
5903|      if ( point.y >= down.y && m_DownY < down.y ) {
5904|        for ( ListX_forEach( &app->m_file.m_prims, &p, ListX_ElemX ) ) {
5905|          prim = (CadPrim*)p->p;   prim->SetHold( false );
5906|        }
5907|        m_DownY = down.y;
5908|      }
5909|
5910|      /* 行を挿入する */
5911|      if ( point.y >= down.y || m_DownY >= down.y ) {
5912|        int  downX = m_DownX;
5913|        int  downY = m_DownY;
5914|        bool  bRebuildBefore = ListX_isEmpty( &m_MultiBefore );
5915|
5916|        dy = ( point.y >= down.y ) ? point.y - m_DownY : down.y - m_DownY;
5917|
5918|        if ( bRebuildBefore )
5919|          m_BeforePrim = app->m_file.m_Canvas.GetNewCopy( &app->m_file.m_prims );
5920|
5921|        for ( ListX_forEach( &app->m_file.m_prims, &p, ListX_ElemX ) ) {
5922|          prim = (CadPrim*)p->p;
5923|          if ( prim->GetForAlign( CadPrim_AlignTop ) >= downY ) {
5924|            prim->Move( 0, dy );
5925|
5926|            y = prim->GetForAlign( CadPrim_AlignBottom );
5927|            if ( y > mostBottomY )  mostBottomY = y;
5928|
5929|            if ( bRebuildBefore ) {
5930|              ListX_ElemX*  p2 = ListX_addLastMalloc( &m_MultiBefore, ListX_ElemX );
5931|              p2->p = ((CadPrim*)p->p)->GetNewCopy( &app->m_file.m_prims );
5932|              ((CadPrim*)p2->p)->SetBInUndoBuf( true );
5933|            }
5934|          }
5935|        }
5936|        if ( m_InkOverlay != NULL ) {
5937|          HRESULT  hr;
5938|          IInkRenderer* render;
5939|          IInkDisp*  ink;
5940|          IInkStrokes*  strokes;
5941|          IInkRectangle*  rc;
5942|          RECT rectX;
5943|          long  dx2 = 0,  dy2 = dy;
5944|          CClientDC  dc(this);
5945|
5946|          hr = m_InkOverlay->get_Ink( &ink );  if ( hr != 0 )  error();
5947|          hr = m_InkOverlay->get_Renderer( &render );  if ( hr != 0 ) error();
5948|          hr = render->PixelToInkSpace( (long)dc.m_hDC, &dx2, &dy2 );  if ( hr != 0 )  error();
5949|
5950|          rectX.left = 0;  rectX.top = downY * m_Zoom / 100;
5951|          rectX.right = app->m_file.m_Canvas.m_Width * m_Zoom / 100;
5952|          rectX.bottom = app->m_file.m_Canvas.m_Height * m_Zoom / 100;
5953|
5954|          if ( rectX.top < rectX.bottom ) {
5955|            pt = GetScrollPosition();
5956|            rectX.left -= pt.x;  rectX.right -= pt.x;
5957|            rectX.top -= pt.y;  rectX.bottom -= pt.y;
5958|
5959|            hr = CoCreateInstance( CLSID_InkRectangle, NULL, CLSCTX_INPROC_SERVER,
5960|                                   IID_IInkRectangle, (void**)&rc );
5961|            if ( hr != 0 )  error();
5962|            hr = render->PixelToInkSpace( (long)dc.m_hDC, &rectX.left, &rectX.top );
5963|            if ( hr != 0 )  error();
5964|            hr = render->PixelToInkSpace( (long)dc.m_hDC, &rectX.right, &rectX.bottom );
5965|            if ( hr != 0 )  error();
5966|            hr = rc->put_Data( rectX );
5967|            if ( hr != 0 )  error();
5968|
5969|            hr = ink->HitTestWithRectangle( rc, 0.0f, &strokes );
5970|            if ( hr != 0 )  error();
5971|            hr = m_InkOverlay->put_Selection( strokes );
5972|            if ( hr != 0 )  error();
5973|
5974|            dy2 = dy2 * m_Zoom / 100;
5975|            hr = strokes->Move( (float)dx2, (float)dy2 );
5976|            if ( hr != 0 ) error();
5977|
5978|            hr = strokes->GetBoundingBox( IBBM_Default, &rc );
5979|            if ( hr != 0 )  error();
5980|            hr = rc->get_Bottom( &dy2 );
5981|            if ( hr != 0 )  error();
5982|            hr = render->InkSpaceToPixel( (long)dc.m_hDC, &dx2, &dy2 );
5983|            if ( hr != 0 )  error();
5984|            if ( dy2 > mostBottomY )  mostBottomY = dy2;
5985|
5986|            hr = strokes->Release();  strokes = NULL;
5987|            hr = rc->Release();  rc = NULL;
5988|          }
5989|          hr = render->Release();  render = NULL;
5990|          hr = ink->Release();  ink = NULL;
5991|        }
5992|
5993|        if ( mostBottomY > m_PrevCanvasHeight - 8 ) {
5994|          app->m_file.m_Canvas.m_Height = mostBottomY + 8;
5995|          m_DownY += dy;
5996|          Redraw( true );  /* ←これがないと、Text_Box GetForAlign() がずれることがある */
5997|          Invalidate( FALSE );
5998|        }
5999|        else {
6000|          app->m_file.m_Canvas.m_Height = m_PrevCanvasHeight;
6001|          m_DownY += dy;
6002|          Redraw( true );
6003|        }
6004|      }
6005|
6006|      /* 行を削除する範囲と削除する図形を表示する */
6007|      if ( point.y < down.y ) {
6008|        ListX_ElemX*  p;
6009|        Rect  rc;
6010|
6011|        Rect_init_by2XY( &rc, 0, point.y, app->m_file.m_Canvas.m_Width, down.y );
6012|        ResetSelect();
6013|        for ( ListX_forEach( &app->m_file.m_prims, &p, ListX_ElemX ) ) {
6014|          ((CadPrim*)p->p)->SetHold( ((CadPrim*)p->p)->IsMultiSelect( &rc ) );
6015|        }
6016|        m_DownY = point.y;
6017|        Redraw( false );
6018|      }
6019|    }
6020|    else {
6021|      SetCursor( app->LoadCursor( IDC_CursorHold2 ) );  /* 図形移動中のカーソル */
6022|    }
6023|  }
6024|  else {
6025|    SetCursorSVGCats( point );
6026|  }
6027|
6028|  if ( frame->m_mode == CMainFrame_Zooming ) {
6029|    CClientDC  dc( this );
6030|    RedrawZoomArea( &dc, point.x, point.y );
6031|  }
6032|
6033|  CScrollView::OnMouseMove(nFlags, point);
6034|  ERRORS_FUNC_END_CPP( CChildView_OnMouseMove );
6035|}
6036|
6037|
6038| 
6039|/***********************************************************************
6040|  40. <<< [CChildView::OnRButtonDown] >>> 
6041|************************************************************************/
6042|void CChildView::OnRButtonDown(UINT nFlags, CPoint point)
6043|{
6044|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
6045|  CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
6046|  CadPrim*  prim;
6047|  int  iHandle;
6048|  int  arrow;
6049|  POINT  pt;
6050|  ListX_ElemX*  p;
6051|  bool  bNotDispMenu = false;
6052|  ERRORS_FUNC_CPP_VAR( CChildView_OnRButtonDown );
6053|  ERRORS_FUNC_START_CPP( CChildView_OnRButtonDown );
6054|
6055|  if ( m_SingleDblClickTimer != 0 )  frame->KillTimer( m_SingleDblClickTimer );
6056|  m_SingleDblClickTimer = 0;
6057|
6058|  frame->m_bScopeHidingCancel = true;
6059|
6060|  if ( m_bDrag ) {
6061|    OnLButtonUp( nFlags, point );
6062|    OnEditRedo();
6063|
6064|    CScrollView ::OnRButtonDown(nFlags, point);
6065|    ERRORS_FUNC_END_CPP( CChildView_OnRButtonDown );
6066|    return;
6067|  }
6068|
6069|  pt = GetScrollPosition();
6070|  point += pt;
6071|  point -= m_MinusOffset;
6072|  point.x = point.x * 100 / m_Zoom;
6073|  point.y = point.y * 100 / m_Zoom;
6074|
6075|  SetCapture();
6076|
6077|  /* カーソルキーによる移動(CadPrim::Move)での操作をアンドゥバッファへ記録する */
6078|  OnFinishPrimMove();
6079|
6080|  /* 図形にヒットしたら、それを選択する */
6081|  if ( nFlags & MK_CONTROL )  prim = NULL;
6082|  else {
6083|    prim = app->GetNearestHandle( point.x, point.y, m_Zoom, frame->GetCadPrimMode(),
6084|      &iHandle, &m_Hold_dx, &m_Hold_dy, &arrow, m_HoldPrim );
6085|  }
6086|
6087|  if ( frame->IsPenMode() ) {
6088|    if ( prim != NULL /*|| point.x <= app->m_file.m_Canvas.m_Width*/ ) {  /* 行操作以外は高速に処理する */
6089|      m_DownX = point.x;  m_DownY = point.y;
6090|      m_Hold_dx = 0;  m_Hold_dy = 0;
6091|      m_bDrag = TRUE;
6092|      m_bInDragPlay = TRUE;
6093|      m_HoldPrim = NULL;
6094|      m_iHoldHandle = 2;
6095|      ResetSelect();
6096|      frame->ResetProp();
6097|      Redraw( false );
6098|
6099|      ERRORS_FUNC_END_CPP( CChildView_OnRButtonDown );
6100|      return;
6101|    }
6102|  }
6103|
6104|  if ( prim == NULL ) {
6105|    SetCursor( NULL );
6106|    if ( m_HoldPrim != NULL )
6107|      bNotDispMenu = true;
6108|    ListX_toEmptyDelete( &m_MultiHolds, ListX_ElemX, NULL );
6109|    for ( ListX_forEach( &app->m_file.m_prims, &p, ListX_ElemX ) )
6110|      ((CadPrim*)p->p)->SetHold( false );
6111|    m_HoldPrim = NULL;
6112|    if ( m_HoldStrokes != NULL )  { m_HoldStrokes->Release();  m_HoldStrokes = NULL; }
6113|    frame->ResetProp();
6114|
6115|    /* 行操作を開始する */
6116|    if ( 1 /*point.x > app->m_file.m_Canvas.m_Width*/ ) {
6117|      m_PrevCanvasHeight = app->m_file.m_Canvas.m_Height;
6118|      m_DownS = point;
6119|      m_DownX = point.x;  m_DownY = point.y;
6120|
6121|      /* アンドゥ用に現在の値を取っておく */
6122|      for ( ListX_forEach( &m_MultiBefore, &p, ListX_ElemX ) )
6123|        delete  (CadPrim*)p->p;
6124|      ListX_toEmptyDelete( &m_MultiBefore, ListX_ElemX, NULL );
6125|
6126|      m_BeforePrim = app->m_file.m_Canvas.GetNewCopy( &app->m_file.m_prims );
6127|
6128|      for ( ListX_forEach( &app->m_file.m_prims, &p, ListX_ElemX ) ) {
6129|        if ( ((CadPrim*)p->p)->GetForAlign( CadPrim_AlignTop ) >= point.y ) {
6130|          ListX_ElemX*  p2 = ListX_addLastMalloc( &m_MultiBefore, ListX_ElemX );
6131|          p2->p = ((CadPrim*)p->p)->GetNewCopy( &app->m_file.m_prims );
6132|          ((CadPrim*)p2->p)->SetBInUndoBuf( true );
6133|        }
6134|      }
6135|
6136|      Redraw( false );
6137|    }
6138|  }
6139|  else {
6140|    for ( ListX_forEach( &m_MultiHolds, &p, ListX_ElemX ) ) {
6141|      if ( p->p == prim )  break;
6142|    }
6143|    if ( p == NULL ) {  /* 選択状態でないものをクリックしたとき */
6144|      ListX_toEmptyDelete( &m_MultiHolds, ListX_ElemX, NULL );
6145|      for ( ListX_forEach( &app->m_file.m_prims, &p, ListX_ElemX ) )
6146|        ((CadPrim*)p->p)->SetHold( false );
6147|      p = ListX_addLastMalloc( &m_MultiHolds, ListX_ElemX );
6148|      p->p = prim;
6149|    }
6150|    else {  /* 選択状態ものものをクリックしたとき */
6151|      ListX_remove( &m_MultiHolds, p );
6152|      ListX_addFirst( &m_MultiHolds, p );
6153|    }
6154|    m_HoldPrim = prim;
6155|    //m_DragPrim = prim;
6156|    //m_iHoldHandle = iHandle;
6157|    frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
6158|
6159|    /* 選択状態の調節 */
6160|    for ( ListX_forEach( &m_MultiHolds, &p, ListX_ElemX ) ) {
6161|      ((CadPrim*)p->p)->SetHold( true );
6162|    }
6163|    SetMultiSelect();
6164|  }
6165|
6166|  m_bRightDrag = ( m_HoldPrim != NULL || m_PrevCanvasHeight >= 0 );
6167|  m_bInDragPlay = m_bRightDrag;
6168|  if ( m_bRightDrag ) {
6169|    m_DownX = point.x;  m_DownY = point.y;
6170|  }
6171|
6172|  frame->SetDefaultMode();
6173|  Redraw( true );
6174|
6175|  m_bRightMenuAble = ( ! bNotDispMenu && prim != NULL );
6176|
6177|  CScrollView::OnRButtonDown(nFlags, point);
6178|
6179|  ERRORS_FUNC_END_CPP( CChildView_OnRButtonDown );
6180|}
6181|
6182|
6183| 
6184|/***********************************************************************
6185|  41. <<< [CChildView::OnRButtonDblClk] >>> 
6186|************************************************************************/
6187|void CChildView::OnRButtonDblClk(UINT nFlags, CPoint point)
6188|{
6189|  ERRORS_FUNC_CPP_VAR( CChildView_OnRButtonDblClk );
6190|  ERRORS_FUNC_START_CPP( CChildView_OnRButtonDblClk );
6191|
6192|  OnRButtonDown( nFlags, point );
6193|
6194|  CScrollView ::OnRButtonDblClk(nFlags, point);
6195|
6196|  ERRORS_FUNC_END_CPP( CChildView_OnRButtonDblClk );
6197|}
6198|
6199|
6200| 
6201|/***********************************************************************
6202|  42. <<< [CChildView::OnRButtonUp] >>> 
6203|************************************************************************/
6204|void CChildView::OnRButtonUp(UINT nFlags, CPoint point)
6205|{
6206|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
6207|  CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
6208|  CMenu   menu;
6209|  POINT  pt;
6210|  POINT  pointOrg = point;
6211|  int  diff;
6212|  ERRORS_FUNC_CPP_VAR( CChildView_OnRButtonUp );
6213|  ERRORS_FUNC_START_CPP( CChildView_OnRButtonUp );
6214|
6215|  pt = GetScrollPosition();
6216|  point += pt;
6217|  point -= m_MinusOffset;
6218|  point.x = point.x * 100 / m_Zoom;
6219|  point.y = point.y * 100 / m_Zoom;
6220|
6221|  EndDragScroll();
6222|  ReleaseCapture();
6223|
6224|  diff = abs( m_DownX - point.x ) + abs( m_DownY - point.y );
6225|
6226|  if ( frame->IsPenMode() ) {
6227|    if ( abs( m_DownX - point.x ) < 8 && abs( m_DownY - point.y ) < 8 ) {
6228|      int  mode = frame->m_mode;
6229|
6230|      frame->m_mode = CMainFrame_Select;
6231|      OnLButtonDown( nFlags, point );
6232|      OnLButtonUp_DlagPrim( nFlags, point );  /* 右ドラッグによる選択の終了 */
6233|      frame->m_mode = mode;
6234|    }
6235|    else
6236|      OnLButtonUp_DlagCanvas( nFlags, point );  /* 右ドラッグによる範囲選択の終了 */
6237|
6238|    m_bCreate = FALSE;
6239|    m_bDrag = FALSE;
6240|    Redraw( false );
6241|
6242|    if ( ! ( m_bRightDrag && ( diff > 7 || m_PrevCanvasHeight >= 0 ) ) &&
6243|             m_PrevCanvasHeight >= 0 ) {  /* 行操作以外は高速に処理する */
6244|      ERRORS_FUNC_END_CPP( CChildView_OnRButtonUp );
6245|      return;
6246|    }
6247|
6248|    m_bRightMenuAble = ( m_HoldPrim != NULL );
6249|    frame->OnSelect();
6250|
6251|    #if 0
6252|    /* 右タップのとき、直前の操作がストロークの追加ならアンドゥする */
6253|    if ( diff < 8 && ! m_bRightMenuAble ) {
6254|      Undo_Step_Com*  now = app->m_UndoBuf->m_Now;
6255|
6256|      if ( now != NULL && now->typeID == Undo_InkType &&
6257|           ((Undo_Step_Ink*)now)->op == Undo_Ink_Add ) {
6258|        ResetSelect();
6259|        OnEditUndo();
6260|      }
6261|    }
6262|    #endif
6263|  }
6264|
6265|  if ( m_bRightDrag && ( diff > 6 || m_PrevCanvasHeight >= 0 ) ) {
6266|
6267|    int  x0, y0, x1, y1;
6268|
6269|    x0 = m_DownX;  y0 = m_DownY;
6270|    x1 = point.x;  y1 = point.y;
6271|    app->m_file.m_Canvas.ChgToGridedPos( &x0, &y0 );
6272|    app->m_file.m_Canvas.ChgToGridedPos( &x1, &y1 );
6273|    m_Hold_dx = x1 - x0;
6274|    m_Hold_dy = y1 - y0;
6275|
6276|    /* 右ドラッグによる行操作 */
6277|    if ( m_PrevCanvasHeight >= 0 ) {
6278|      CPoint  down;
6279|      ListX_ElemX*  p;
6280|      ListX_ElemX*  p2;
6281|
6282|      down = m_DownS;
6283|
6284|      app->m_UndoBuf->StartMulti();
6285|
6286|      /* 行挿入の結果をアンドゥバッファに入れる */
6287|      if ( point.y >= down.y ) {
6288|
6289|        app->m_UndoBuf->AllocNewStep( m_BeforePrim,
6290|          app->m_file.m_Canvas.GetNewCopy( &app->m_file.m_prims ), NULL, NULL,
6291|          app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
6292|        m_BeforePrim = NULL;
6293|
6294|        p2 = ListX_getFirst( &m_MultiBefore, ListX_ElemX );
6295|        for ( ListX_forEach( &app->m_file.m_prims, &p, ListX_ElemX ) ) {
6296|          if ( ((CadPrim*)p->p)->GetForAlign( CadPrim_AlignTop ) >= point.y ) {
6297|            app->m_UndoBuf->AllocNewStep( (CadPrim*)p2->p,
6298|              ((CadPrim*)p->p)->GetNewCopy( &app->m_file.m_prims ), NULL, NULL,
6299|              app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
6300|            p2 = ListX_Elem_getNextT( p2, ListX_ElemX );
6301|          }
6302|        }
6303|        ListX_toEmptyDelete( &m_MultiBefore, ListX_ElemX, NULL );
6304|
6305|        if ( m_InkOverlay != NULL ) {
6306|          IInkDisp*  ink;
6307|          IInkStrokes*  strokes;
6308|          IInkRenderer*  render;
6309|          HRESULT  hr;
6310|          long  dx2 = 0,  dy2 = point.y - down.y;
6311|          CClientDC  dc(this);
6312|
6313|          hr = m_InkOverlay->get_Renderer( &render );  if ( hr != 0 ) error();
6314|          hr = render->PixelToInkSpace( (long)dc.m_hDC, &dx2, &dy2 );  if ( hr != 0 )  error();
6315|          render->Release();
6316|
6317|          hr = m_InkOverlay->get_Ink( &ink );  if ( hr != 0 )  error();
6318|          hr = m_InkOverlay->get_Selection( &strokes );  if ( hr != 0 )  error();
6319|          app->m_UndoBuf->AllocNewStep_Ink( Undo_Ink_Move, ink, strokes, 0, dy2,
6320|            app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
6321|          hr = strokes->Release();  strokes = NULL;
6322|          hr = ink->Release();  ink = NULL;
6323|
6324|          SelectInkToEmpty();
6325|        }
6326|      }
6327|
6328|      /* 行削除する */
6329|      else {
6330|
6331|        /* 矩形領域を選択する */
6332|        for ( ListX_forEach( &app->m_file.m_prims, &p, ListX_ElemX ) ) {
6333|          ((CadPrim*)p->p)->SetHold( false );
6334|        }
6335|        m_PrevCanvasHeight = point.y - down.y;
6336|        m_DownX = 0;
6337|        m_DownY = point.y;
6338|        point.x = app->m_file.m_Canvas.m_Width;
6339|        point.y = down.y;
6340|        m_iHoldHandle = 2;
6341|        OnLButtonUp_DlagCanvas( 0, point );
6342|
6343|        /* 図形も削除するか確認する */
6344|        if ( m_HoldPrim != NULL || GetSelectedStrokeCount() != 0 ) {
6345|          Sleep(500);
6346|          switch ( MessageBox(
6347|              app->m_bJapanese ? "選択した図形も削除しますか?" : "Do you delete selected figure too ?",
6348|              app->m_bJapanese ? "行削除" : "Delete Row", MB_YESNOCANCEL ) ) {
6349|            case IDYES:  OnDel();  break;
6350|            case IDNO:   break;
6351|            case IDCANCEL:   m_PrevCanvasHeight = -1;  break;
6352|          }
6353|          ResetSelect();
6354|        }
6355|
6356|        /* キャンバスを縮める */
6357|        if ( m_PrevCanvasHeight != -1 ) {
6358|          int  dy = m_DownY - point.y;
6359|          CadPrim*  canvas;
6360|          POINT  pt = GetScrollPosition();
6361|
6362|          m_DownX = 0;
6363|          m_DownY = down.y;
6364|          point.x = app->m_file.m_Canvas.m_Width;
6365|          point.y = app->m_file.m_Canvas.m_Height;
6366|          m_iHoldHandle = 2;
6367|          OnLButtonUp_DlagCanvas( 0, point );
6368|
6369|          ASSERT( ListX_getN( &m_MultiBefore, ListX_ElemX ) == 0 );
6370|          for ( ListX_forEach( &m_MultiSelects, &p, ListX_ElemX ) ) {
6371|            p2 = ListX_addLastMalloc( &m_MultiBefore, ListX_ElemX );
6372|            p2->p = ((CadPrim*)p->p)->GetNewCopy( &app->m_file.m_prims );
6373|            ((CadPrim*)p2->p)->SetBInUndoBuf( true );
6374|          }
6375|
6376|          point.x = m_DownX * m_Zoom / 100 - pt.x;
6377|          point.y = (m_DownY + dy) * m_Zoom / 100 - pt.y;
6378|          m_bDrag = true;
6379|          m_iHoldHandle = -2;
6380|          OnMouseMove( 0, point );
6381|          EndDragScroll();
6382|          m_bDrag = false;
6383|
6384|          canvas = app->m_file.m_Canvas.GetNewCopy( &app->m_file.m_prims );
6385|          app->m_file.m_Canvas.m_Height += dy;
6386|
6387|          /* アンドゥバッファに記録する */
6388|          app->m_UndoBuf->AllocNewStep( canvas,
6389|            app->m_file.m_Canvas.GetNewCopy( &app->m_file.m_prims ), NULL, NULL,
6390|            app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
6391|
6392|          p2 = ListX_getFirst( &m_MultiBefore, ListX_ElemX );
6393|          for ( ListX_forEach( &m_MultiSelects, &p, ListX_ElemX ) ) {
6394|            app->m_UndoBuf->AllocNewStep( (CadPrim*)p2->p,
6395|              ((CadPrim*)p->p)->GetNewCopy( &app->m_file.m_prims ), NULL, NULL,
6396|              app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
6397|            p2 = ListX_Elem_getNextT( p2, ListX_ElemX );
6398|          }
6399|          ListX_toEmptyDelete( &m_MultiBefore, ListX_ElemX, NULL );
6400|
6401|          if ( m_InkOverlay != NULL ) {
6402|            IInkDisp*  ink;
6403|            IInkStrokes*  strokes;
6404|            IInkRenderer*  render;
6405|            long  dx2 = 0,  dy2 = dy;
6406|            HRESULT  hr;
6407|            CClientDC  dc(this);
6408|
6409|            hr = m_InkOverlay->get_Renderer( &render );  if ( hr != 0 ) error();
6410|            hr = render->PixelToInkSpace( (long)dc.m_hDC, &dx2, &dy2 );  if ( hr != 0 )  error();
6411|            render->Release();
6412|
6413|            hr = m_InkOverlay->get_Ink( &ink );  if ( hr != 0 )  error();
6414|            hr = ink->get_Strokes( &strokes );  if ( hr != 0 )  error();
6415|            app->m_UndoBuf->AllocNewStep_Ink( Undo_Ink_Move, ink, strokes,
6416|              0, dy2, app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
6417|            hr = strokes->Release();  strokes = NULL;
6418|            hr = ink->Release();  ink = NULL;
6419|          }
6420|
6421|          ResetSelect( true );
6422|        }
6423|      }
6424|      m_PrevCanvasHeight = -1;
6425|      Redraw( true );
6426|      SetScrollSize();
6427|
6428|      app->m_UndoBuf->EndMulti();
6429|    }
6430|
6431|    /* 右ドラッグによる移動かコピー */
6432|    else {
6433|      if ( ( GetKeyState( VK_CONTROL ) & 0xF000 ) &&
6434|          !( GetKeyState( VK_SHIFT ) & 0xF000) )
6435|        OnDragCopy();
6436|
6437|      else if ( ( GetKeyState( VK_SHIFT ) & 0xF000 ) &&
6438|          !( GetKeyState( VK_CONTROL ) & 0xF000) )
6439|        OnDragMove();
6440|
6441|
6442|      /* 右ドラッグメニューを表示する */
6443|      else {
6444|        ClientToScreen( &pointOrg );
6445|
6446|        pointOrg.x -= 32;
6447|        pointOrg.y -= 12;
6448|
6449|        menu.Attach( m_DragMenu );
6450|
6451|        TrackPopupMenu( m_DragMenu, TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
6452|          pointOrg.x, pointOrg.y, 0, frame->m_hWnd, NULL );
6453|
6454|        menu.Detach();
6455|      }
6456|    }
6457|  }
6458|  else if ( m_bRightMenuAble ) {
6459|
6460|    /* 右クリックメニューを表示する */
6461|    ClientToScreen( &pointOrg );
6462|    pointOrg.x += 2;
6463|
6464|    menu.Attach( m_PrimRightMenu );
6465|    menu.CheckMenuItem( ID_DispProp, MF_BYCOMMAND |
6466|      frame->m_PropBar.IsWindowVisible() ? MF_CHECKED : MF_UNCHECKED );
6467|
6468|    TrackPopupMenu( m_PrimRightMenu, TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
6469|      pointOrg.x, pointOrg.y, 0, frame->m_hWnd, NULL );
6470|
6471|    menu.Detach();
6472|  }
6473|
6474|  m_bRightDrag = false;
6475|  m_bInDragPlay = FALSE;
6476|  m_bRightMenuAble = false;
6477|
6478|  CScrollView ::OnRButtonUp(nFlags, point);
6479|
6480|  ERRORS_FUNC_END_CPP( CChildView_OnRButtonUp );
6481|}
6482|
6483|
6484| 
6485|/***********************************************************************
6486|  43. <<< [CChildView::OnDragCopy] >>> 
6487|************************************************************************/
6488|void CChildView::OnDragCopy()
6489|{
6490|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
6491|  CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
6492|  ListX_ElemX*  p;
6493|  ListX_ElemX*  p2;
6494|  ListX  prims;
6495|  CadPrim*  prim;
6496|  ListX  ids;
6497|  int    newID;
6498|  StrX_ListElem2*  sp;
6499|  ERRORS_FUNC_CPP_VAR( CChildView_OnDragCopy );
6500|  ERRORS_FUNC_START_CPP( CChildView_OnDragCopy );
6501|
6502|  ListX_init( &prims );
6503|  ListX_init( &ids );
6504|  app->m_UndoBuf->StartMulti();
6505|  for ( ListX_forEach( &m_MultiSelects, &p, ListX_ElemX ) ) {
6506|    ((CadPrim*)p->p)->SetHold( false );
6507|
6508|    prim = ((CadPrim*)p->p)->GetNewCopy( &app->m_file.m_prims );
6509|    p2 = ListX_addFirstMalloc( &prims, ListX_ElemX );
6510|    p2->p = prim;
6511|
6512|    newID = app->GetNewPrimID();
6513|    sp = ListX_addFirstMalloc( &ids, StrX_ListElem2 );
6514|    sp->p = (char*)prim->GetID();  sp->data = (void*)newID;
6515|    prim->SetID( newID );
6516|  }
6517|
6518|  ListX_toEmptyDelete( &m_MultiHolds, ListX_ElemX, NULL );
6519|  m_MultiHolds.first = prims.first;
6520|  for ( ListX_forEach( &m_MultiHolds, &p, ListX_ElemX ) ) {
6521|    prim = (CadPrim*)p->p;
6522|    app->AddPrim( &app->m_file, prim );
6523|    prim->SetHold( true );
6524|  }
6525|
6526|  PasteAdjust( &ids, m_Hold_dx, m_Hold_dy );
6527|
6528|  ListX_reverse( &m_MultiSelects, ListX_ElemX );  /* 手前から */
6529|  for ( ListX_forEach( &m_MultiSelects, &p, ListX_ElemX ) ) {
6530|    app->m_UndoBuf->AllocNewStep( NULL,
6531|    ((CadPrim*)p->p)->GetNewCopy( &app->m_file.m_prims ), NULL, NULL,
6532|        app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
6533|  }
6534|  ListX_reverse( &m_MultiSelects, ListX_ElemX );
6535|
6536|  app->m_UndoBuf->EndMulti();
6537|
6538|  ListX_toEmptyDelete( &ids, StrX_ListElem2, NULL );
6539|
6540|  AnimateOnPaste();
6541|
6542|  ERRORS_FUNC_END_CPP( CChildView_OnDragCopy );
6543|}
6544|
6545|
6546|void CChildView::OnDragMove()
6547|{
6548|  CPoint  point;
6549|  CPoint  point0( m_DownX, m_DownY );
6550|  CPoint  point1( m_DownX + m_Hold_dx,  m_DownY + m_Hold_dy );
6551|  UINT  nFlag = 0;
6552|  int  i;
6553|  DWORD  tm, tm2;
6554|  POINT  pt;
6555|  int  j[31];
6556|  enum { interval = 12 };
6557|  ERRORS_FUNC_CPP_VAR( CChildView_OnDragMove );
6558|  ERRORS_FUNC_START_CPP( CChildView_OnDragMove );
6559|
6560|  pt = GetScrollPosition();
6561|  point0.x = point0.x * m_Zoom / 100;
6562|  point0.y = point0.y * m_Zoom / 100;
6563|  point1.x = point1.x * m_Zoom / 100;
6564|  point1.y = point1.y * m_Zoom / 100;
6565|  point0 -= pt;
6566|  point1 -= pt;
6567|  OnLButtonDown( nFlag, point0 );
6568|
6569|  j[0] = 0;
6570|  tm = GetTickCount();
6571|  for ( i = 1; i <= 30; i++ ) {
6572|    j[i] = j[i-1] + i;
6573|  }
6574|
6575|  for ( i = 1; i <= 30; i++ ) {
6576|    tm2 = GetTickCount();
6577|    if ( tm2 - tm > interval )
6578|      { i += (tm2 - tm) / interval;  if ( i > 30 )  i = 30; }
6579|    if ( tm2 - tm < interval )  Sleep( interval - (tm2 - tm) );
6580|    tm = tm2;
6581|    point.x = ( point0.x * ( 465 - j[i] ) + point1.x * j[i] ) / 465;
6582|    point.y = ( point0.y * ( 465 - j[i] ) + point1.y * j[i] ) / 465;
6583|    OnMouseMove( 0, point );
6584|  }
6585|  OnLButtonUp( 0, point1 );
6586|
6587|  ERRORS_FUNC_END_CPP( CChildView_OnDragMove );
6588|}
6589|
6590|
6591|void CChildView::OnDragCancel()
6592|{
6593|  /* DoNothing */
6594|}
6595|
6596|
6597| 
6598|/***********************************************************************
6599|  44. <<< [CChildView::AutoAdjustXY] マウス操作の座標を自動補正する >>> 
6600|【引数】
6601|  ・long*  x, y;        キャンバス座標
6602|  ・bool  bAutoAdjust;  自動補正するかどうか
6603|  ・bool  bHoriVert;    元の位置より水平または垂直に制限するかどうか
6604|************************************************************************/
6605|void  CChildView::AutoAdjustXY( long* x, long* y, bool bAutoAdjust, bool bHoriVert )
6606|{
6607|  CSVGCatApp*   app = (CSVGCatApp*)AfxGetApp();
6608|  enum { diff = 6 };
6609|  int  dx = diff + 1;
6610|  int  dy = diff + 1;
6611|  int  d;
6612|  int  xx = *x;
6613|  int  yy = *y;
6614|  bool  bDisableX = false;
6615|  bool  bDisableY = false;
6616|  ListX_ElemX*  p;
6617|
6618|  /* コントロールキーで移動を水平移動または垂直移動にする */
6619|  if ( bHoriVert ) {
6620|    CPoint  down;
6621|    int dx,dy;
6622|
6623|    if ( m_iHoldHandle == -1 ) {
6624|      down = m_DownS;
6625|      dx = down.x - (xx - m_Hold_dx);  if ( dx < 0 )  dx = -dx;
6626|      dy = down.y - (yy - m_Hold_dy);  if ( dy < 0 )  dy = -dy;
6627|      if ( dx > dy )  { *y = down.y + m_Hold_dy;  bDisableY = true; }
6628|      else            { *x = down.x + m_Hold_dx;  bDisableX = true; }
6629|    }
6630|    else {
6631|      down = m_DownS;
6632|      dx = down.x - xx;  if ( dx < 0 )  dx = -dx;
6633|      dy = down.y - yy;  if ( dy < 0 )  dy = -dy;
6634|      if ( dx > dy )  { *y = down.y;  bDisableY = true; }
6635|      else            { *x = down.x;  bDisableX = true; }
6636|    }
6637|  }
6638|
6639|  if ( bAutoAdjust ) {
6640|    for ( ListX_forEach( &app->m_file.m_prims, &p, ListX_ElemX ) ) {
6641|      if ( p->p == m_HoldPrim )  continue;
6642|      if ( ((CadPrim*)p->p)->GetTypeID() == Line_Ex_TypeID ) {
6643|        Line*  line = &((Line_Ex*)p->p)->m_Line;
6644|
6645|        /* ラインの頂点に自動補正する */
6646|        d = line->x1 - *x;  if ( d < 0 )  d = -d;
6647|        if ( d < dx ) {
6648|          d = line->y1 - *y;  if ( d < 0 )  d = -d;
6649|          if ( d < dy ) {
6650|            yy = line->y1;  dy = *y - line->y1;  if ( dy < 0 )  dy = -dy;
6651|            xx = line->x1;  dx = *x - line->x1;  if ( dx < 0 )  dx = -dx;
6652|          }
6653|        }
6654|
6655|        d = line->x2 - *x;  if ( d < 0 )  d = -d;
6656|        if ( d < dx ) {
6657|          d = line->y2 - *y;  if ( d < 0 )  d = -d;
6658|          if ( d < dy ) {
6659|            yy = line->y2;  dy = *y - line->y2;  if ( dy < 0 )  dy = -dy;
6660|            xx = line->x2;  dx = *x - line->x2;  if ( dx < 0 )  dx = -dx;
6661|          }
6662|        }
6663|
6664|        /* 水平線や垂直線に自動補正する */
6665|        if ( line->x1 == line->x2 ) {
6666|          d = line->x1 - *x;  if ( d < 0 )  d = -d;
6667|          if ( d < dx )
6668|            { xx = line->x1;  dx = *x - line->x1;  if ( dx < 0 )  dx = -dx; }
6669|        }
6670|        else if ( line->y1 == line->y2 ) {
6671|          d = line->y1 - *y;  if ( d < 0 )  d = -d;
6672|          if ( d < dy )
6673|            { yy = line->y1;  dy = *y - line->y1;  if ( dy < 0 )  dy = -dy; }
6674|        }
6675|      }
6676|
6677|      if ( ((CadPrim*)p->p)->GetTypeID() == Line_Corner_TypeID ) {
6678|        Line*  line = &((Line_Corner*)p->p)->m_Line;
6679|        Line_Corner*  lc = (Line_Corner*)p->p;
6680|        int  i;
6681|
6682|        /* ラインの頂点に自動補正する */
6683|        d = line->x1 - *x;  if ( d < 0 )  d = -d;
6684|        if ( d < dx ) {
6685|          d = line->y1 - *y;  if ( d < 0 )  d = -d;
6686|          if ( d < dy ) {
6687|            yy = line->y1;  dy = *y - line->y1;  if ( dy < 0 )  dy = -dy;
6688|            xx = line->x1;  dx = *x - line->x1;  if ( dx < 0 )  dx = -dx;
6689|          }
6690|        }
6691|
6692|        d = line->x2 - *x;  if ( d < 0 )  d = -d;
6693|        if ( d < dx ) {
6694|          d = line->y2 - *y;  if ( d < 0 )  d = -d;
6695|          if ( d < dy ) {
6696|            yy = line->y2;  dy = *y - line->y2;  if ( dy < 0 )  dy = -dy;
6697|            xx = line->x2;  dx = *x - line->x2;  if ( dx < 0 )  dx = -dx;
6698|          }
6699|        }
6700|
6701|        /* 最初と最後の水平線や垂直線に自動補正する */
6702|        if ( lc->m_LinesX[0] == lc->m_LinesX[1] ) {
6703|          d = lc->m_LinesX[0] - *x;  if ( d < 0 )  d = -d;
6704|          if ( d < dx )
6705|            { xx = lc->m_LinesX[0];  dx = *x - lc->m_LinesX[0];  if ( dx < 0 )  dx = -dx; }
6706|        }
6707|        else if ( lc->m_LinesY[0] == lc->m_LinesY[1] ) {
6708|          d = lc->m_LinesY[0] - *y;  if ( d < 0 )  d = -d;
6709|          if ( d < dy )
6710|            { yy = lc->m_LinesY[0];  dy = *y - lc->m_LinesY[0];  if ( dy < 0 )  dy = -dy; }
6711|        }
6712|        if ( lc->m_LinesX[lc->m_LinesN - 1] == lc->m_LinesX[lc->m_LinesN - 2] ) {
6713|          d = lc->m_LinesX[lc->m_LinesN - 1] - *x;  if ( d < 0 )  d = -d;
6714|          if ( d < dx )
6715|            { xx = lc->m_LinesX[lc->m_LinesN - 1];  dx = *x - lc->m_LinesX[lc->m_LinesN - 1];  if ( dx < 0 )  dx = -dx; }
6716|        }
6717|        else if ( lc->m_LinesY[lc->m_LinesN - 1] == lc->m_LinesY[lc->m_LinesN - 2] ) {
6718|          d = lc->m_LinesY[lc->m_LinesN - 1] - *y;  if ( d < 0 )  d = -d;
6719|          if ( d < dy )
6720|            { yy = lc->m_LinesY[lc->m_LinesN - 1];  dy = *y - lc->m_LinesY[lc->m_LinesN - 1];  if ( dy < 0 )  dy = -dy; }
6721|        }
6722|
6723|        /* 通過点を通るラインに自動補正する */
6724|        for ( i = 0; i < lc->m_LinesN - 1; i++ ) {
6725|          if ( lc->m_CornerX == lc->m_LinesX[i] && lc->m_CornerX == lc->m_LinesX[i+1] &&
6726|               lc->m_CornerY != lc->m_LinesY[i] && lc->m_CornerY != lc->m_LinesY[i+1] ) {
6727|            d = lc->m_LinesX[i] - *x;  if ( d < 0 )  d = -d;
6728|            if ( d < dx )
6729|              { xx = lc->m_LinesX[i];  dx = *x - lc->m_LinesX[i];  if ( dx < 0 )  dx = -dx; }
6730|            break;
6731|          }
6732|          if ( lc->m_CornerX != lc->m_LinesX[i] && lc->m_CornerX != lc->m_LinesX[i+1] &&
6733|               lc->m_CornerY == lc->m_LinesY[i] && lc->m_CornerY == lc->m_LinesY[i+1] ) {
6734|            d = lc->m_LinesY[i] - *y;  if ( d < 0 )  d = -d;
6735|            if ( d < dy )
6736|              { yy = lc->m_LinesY[i];  dy = *y - lc->m_LinesY[i];  if ( dy < 0 )  dy = -dy; }
6737|            break;
6738|          }
6739|        }
6740|      }
6741|    }
6742|  }
6743|
6744|  if ( ! bDisableX )  *x = xx;
6745|  if ( ! bDisableY )  *y = yy;
6746|}
6747|
6748|
6749| 
6750|/***********************************************************************
6751|  45. <<< [CChildView::OnCatchGrid] グリッドするモードを設定する >>> 
6752|************************************************************************/
6753|void CChildView::OnCatchGrid()
6754|{
6755|  CSVGCatApp*   app = (CSVGCatApp*)AfxGetApp();
6756|  app->m_file.m_Canvas.m_bGridOn = ! app->m_file.m_Canvas.m_bGridOn;
6757|
6758|  if ( app->m_file.m_Canvas.m_bGridOn )
6759|    app->m_file.m_Canvas.m_GridDrawType = Canvas_DotGrid;
6760|  else
6761|    app->m_file.m_Canvas.m_GridDrawType = Canvas_NoGrid;
6762|
6763|  Redraw( FALSE );
6764|  app->SaveSVGCatsIni();
6765|}
6766|
6767|
6768|void CChildView::OnUpdateCatchGrid(CCmdUI* pCmdUI)
6769|{
6770|  CSVGCatApp*   app = (CSVGCatApp*)AfxGetApp();
6771|  pCmdUI->SetCheck( app->m_file.m_Canvas.m_bGridOn );
6772|}
6773|
6774|
6775|void CChildView::OnDisplayGrid()
6776|{
6777|  CSVGCatApp*   app = (CSVGCatApp*)AfxGetApp();
6778|
6779|  if ( app->m_file.m_Canvas.m_GridDrawType == Canvas_NoGrid )
6780|    app->m_file.m_Canvas.m_GridDrawType = Canvas_DotGrid;
6781|  else
6782|    app->m_file.m_Canvas.m_GridDrawType = Canvas_NoGrid;
6783|
6784|  Redraw( FALSE );
6785|  app->SaveSVGCatsIni();
6786|}
6787|
6788|
6789|void CChildView::OnUpdateDisplayGrid(CCmdUI* pCmdUI)
6790|{
6791|  CSVGCatApp*   app = (CSVGCatApp*)AfxGetApp();
6792|  pCmdUI->SetCheck( app->m_file.m_Canvas.m_GridDrawType != Canvas_NoGrid );
6793|}
6794|
6795|
6796|void CChildView::OnGridSizePixel()
6797|{
6798|  CSVGCatApp*   app = (CSVGCatApp*)AfxGetApp();
6799|  app->m_file.m_Canvas.m_bGridOn = true;
6800|  app->m_file.m_Canvas.m_GridDrawType = Canvas_DotGrid;
6801|  app->m_file.m_Canvas.m_GridWidth = 12;
6802|  app->m_file.m_Canvas.m_GridHeight = 12;
6803|
6804|  Redraw( FALSE );
6805|}
6806|
6807|void CChildView::OnUpdateGridSizePixel(CCmdUI* pCmdUI)
6808|{
6809|  CSVGCatApp*   app = (CSVGCatApp*)AfxGetApp();
6810|  pCmdUI->SetCheck( app->m_file.m_Canvas.m_GridWidth == 12 );
6811|}
6812|
6813|void CChildView::OnGridSizeMeter()
6814|{
6815|  CSVGCatApp*   app = (CSVGCatApp*)AfxGetApp();
6816|  app->m_file.m_Canvas.m_bGridOn = true;
6817|  app->m_file.m_Canvas.m_GridDrawType = Canvas_DotGrid;
6818|  app->m_file.m_Canvas.m_GridWidth = 19;
6819|  app->m_file.m_Canvas.m_GridHeight = 19;
6820|
6821|  Redraw( FALSE );
6822|}
6823|
6824|void CChildView::OnUpdateGridSizeMeter(CCmdUI* pCmdUI)
6825|{
6826|  CSVGCatApp*   app = (CSVGCatApp*)AfxGetApp();
6827|  pCmdUI->SetCheck( app->m_file.m_Canvas.m_GridWidth == 19 );
6828|}
6829|
6830|
6831| 
6832|void CChildView::OnSetStdGrid() 
6833|{
6834|  CSVGCatApp*   app = (CSVGCatApp*)AfxGetApp();
6835|  CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
6836|
6837|  app->m_file.m_Canvas.m_bGridOn = true;
6838|  app->m_file.m_Canvas.m_GridDrawType = Canvas_DotGrid;
6839|  app->m_file.m_Canvas.m_GridWidth = 19;
6840|  app->m_file.m_Canvas.m_GridHeight = 19;
6841|
6842|  Redraw( FALSE );
6843|  frame->ResetProp();
6844|}
6845|
6846|
6847| 
6848|/***********************************************************************
6849|  46. <<< [CChildView::OnStroke] ペンで描いたときの処理 >>> 
6850|************************************************************************/
6851|void  CChildView::OnStroke( IInkCursor* cursor, IInkStrokeDisp* stroke, VARIANT_BOOL* cancel )
6852|{
6853|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
6854|  CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
6855|  HRESULT  hr;
6856|  IInkDisp*  ink;
6857|  InkOverlayEditingMode  mode;
6858|  #ifndef NDEBUG
6859|    int  nInk = GetInkCount();
6860|  #endif
6861|  ERRORS_FUNC_CPP_VAR( CChildView_OnStroke );
6862|  ERRORS_FUNC_START_CPP( CChildView_OnStroke );
6863|
6864|  if ( m_bRightTap ) {
6865|
6866|    /* 右クリックの処理は、CChildView::OnRButtomUp 等で行う */
6867|
6868|    /* 描画しないようにしていた設定を元に戻す */
6869|    hr = m_InkOverlay->put_DynamicRendering( VARIANT_TRUE );
6870|    if ( hr != 0 )  error();
6871|
6872|    m_bRightTap = false;
6873|
6874|    *cancel = VARIANT_TRUE;  /* これで、作成したストロークは削除される */
6875|    return;
6876|  }
6877|
6878|  hr = m_InkOverlay->get_EditingMode( &mode );
6879|  if ( hr != 0 )  error();
6880|
6881|  if ( mode == IOEM_Ink && ! m_bMyInkSelectMode ) {
6882|
6883|    /* アンドゥ領域に記録する */
6884|    m_EmptyStrokes->Add( stroke );
6885|    app->m_UndoBuf->AllocNewStep_Ink2( Undo_Ink_Add, m_Ink, m_EmptyStrokes,
6886|      false, app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
6887|    m_EmptyStrokes->Remove( stroke );
6888|  }
6889|
6890|  else if ( mode == IOEM_Ink && m_bMyInkSelectMode ) {  // mode == IOEM_Select の代わり
6891|    long  n;
6892|
6893|
6894|    /* ロープで囲んだインクのストロークを m_HoldStrokes にコピーする */
6895|    Variant_finish( &m_PointsOnStroke );
6896|    Variant_initEmpty( &m_PointsOnStroke );
6897|    if ( m_HoldStrokes != NULL )  { hr = m_HoldStrokes->Release();  m_HoldStrokes = NULL; }
6898|
6899|    hr = m_InkOverlay->get_Ink( &ink );
6900|    if ( hr != S_OK )  error();
6901|
6902|    hr = stroke->GetPoints( 0, -1, &m_PointsOnStroke );
6903|    if ( hr != S_OK )  error();
6904|
6905|    hr = ink->HitTestWithLasso( m_PointsOnStroke, 60.0f, NULL, &m_HoldStrokes );
6906|    if ( hr == E_INVALIDARG )  n = 0;  /* ロープでクリックだけしたとき */
6907|    else if ( hr != S_OK )  error();
6908|    else  m_HoldStrokes->get_Count( &n );  /* n は、捕まえたストローク+1 */
6909|
6910|    if ( n > 0 ) {
6911|      hr = m_HoldStrokes->Remove( stroke );  /* 最後のストロークはロープ */
6912|      if ( hr != S_OK )  error();
6913|      n--;
6914|    }
6915|    // DebugDrawStrokes( m_HoldStrokes );
6916|
6917|    hr = ink->DeleteStroke( stroke );
6918|    if ( hr != 0 )  error();
6919|
6920|
6921|    if ( n > 0 ) {
6922|
6923|      SetResizeHandle();
6924|
6925|      /* 選択モードにする */
6926|      hr = m_InkOverlay->put_Selection( m_HoldStrokes );
6927|      if ( hr != 0 )  error();
6928|
6929|      #if 1
6930|        frame->PostMessage( WM_COMMAND, ID_Select );
6931|      #else
6932|
6933|        hr = m_InkOverlay->put_EditingMode( IOEM_Select );
6934|        if ( hr != 0 )  error();
6935|
6936|        hr = m_InkOverlay->put_MousePointer( IMP_Default );
6937|        if ( hr != 0 )  error();
6938|      #endif
6939|    }
6940|
6941|    hr = ink->Release();  ink = NULL;
6942|
6943|    m_RopeLeaderPos.x = -99999;
6944|    m_RopeLeaderPos.y = -99999;
6945|    m_RopeNPoint = 0;
6946|    PostMessage( WM_COMMAND, ID_SetPropMulti );
6947|    Invalidate( FALSE );
6948|  }
6949|
6950|
6951|//  ASSERT( nInk == GetInkCount() );
6952|  ERRORS_FUNC_END_CPP( CChildView_OnStroke );
6953|}
6954|
6955|
6956| 
6957|/***********************************************************************
6958|  47. <<< [CChildView::OnNewPackets] ストロークの頂点が増えたときの処理 >>> 
6959|【補足】
6960|・IInkOverlay の標準 Rasso は遅いため、この関数などで改良しています。
6961|************************************************************************/
6962|void  CChildView::OnNewPackets( IInkCursor* Cursor, IInkStrokeDisp* stroke,
6963|  long PacketCount, VARIANT* PacketData )
6964|{
6965|  CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
6966|  VARIANT  points;
6967|  IInkRenderer*  render;
6968|  long  x, y;
6969|  long  n;
6970|  HRESULT  hr;
6971|
6972|  if ( m_RopeNPoint < 0 )  return;
6973|
6974|  /* 新しいパケットの座標 x,y を取得する */
6975|  Variant_initEmpty( &points );
6976|
6977|  SafeArrayGetLBound( PacketData->parray, 1, &x );
6978|  SafeArrayGetUBound( PacketData->parray, 1, &y );
6979|  n = 0;
6980|  SafeArrayGetElement( PacketData->parray, &n, &x );
6981|  n = 1;
6982|  SafeArrayGetElement( PacketData->parray, &n, &y );
6983|
6984|  Variant_finish( &points );
6985|
6986|
6987|  /* 投げ縄の頂点を記録する */
6988|  if ( abs( x - m_RopeLeaderPos.x ) + abs( y - m_RopeLeaderPos.y ) > 300 ) {
6989|    m_RopeLeaderPos.x = x;  m_RopeLeaderPos.y = y;
6990|
6991|    if ( m_RopeNPoint < CChildView_RopeMPoint ) {
6992|
6993|      hr = m_InkOverlay->get_Renderer( &render );  if ( hr != 0 )  error();
6994|      render->InkSpaceToPixel( (long)m_BitmapDC.m_hDC, &x, &y );
6995|
6996|      m_RopePoints[m_RopeNPoint].x = x;  m_RopePoints[m_RopeNPoint].y = y;
6997|      m_RopeNPoint ++;
6998|
6999|      render->Release();
7000|    }
7001|  }
7002|}
7003|
7004|
7005|void  CChildView::OnDrawRopeTiming()
7006|{
7007|  CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
7008|  static int  nPrevNPoint = 0;
7009|
7010|  if ( nPrevNPoint == m_RopeNPoint )  return;
7011|
7012|  nPrevNPoint = m_RopeNPoint;
7013|
7014|  /* 投げ縄の輪郭を描く */
7015|  COLORREF  color = GetSysColor( COLOR_HIGHLIGHT );
7016|  CPen     pen( PS_DASHDOT, 1, color ^ 0xFFFFFF );
7017|  CPen     dashPen( PS_DASHDOT, 1, color );
7018|  CBrush   brush( HS_FDIAGONAL, color );
7019|  CPen*    oldPen;
7020|  CBrush*  oldBrush;
7021|  CClientDC  dc(this);
7022|
7023|  Redraw(false);
7024|
7025|  oldPen = dc.SelectObject( &pen );
7026|  oldBrush = dc.SelectObject( &brush );
7027|
7028|  dc.SetBkMode( TRANSPARENT );
7029|  dc.Polygon( m_RopePoints, m_RopeNPoint );
7030|
7031|  dc.SelectObject( &dashPen );
7032|  dc.SetBkMode( OPAQUE );
7033|  dc.SetBkColor( color ^ 0xFFFFFF );
7034|  dc.Polyline( m_RopePoints, m_RopeNPoint );
7035|
7036|  dc.SelectObject( oldBrush );
7037|  dc.SelectObject( oldPen );
7038|
7039|  m_RopeTimer = frame->SetTimer( CMainFrame_Timer_DrawRope, 100, NULL );
7040|}
7041|
7042| 
7043|/***********************************************************************
7044|  48. <<< [CChildView::OnCursorDown] ペンで描き始めたときの処理 >>> 
7045|************************************************************************/
7046|void  CChildView::OnCursorDown( IInkCursor* cursor, IInkStrokeDisp* stroke )
7047|{
7048|  m_DrawingStroke = stroke;
7049|}
7050|
7051| 
7052|/***********************************************************************
7053|  49. <<< [CChildView::OnSystemGesture] システム関係の通知を受けたときの処理 >>> 
7054|************************************************************************/
7055|void  CChildView::OnSystemGesture( IInkCursor* Cursor, InkSystemGesture Id,
7056|  long X, long Y, long Modifier, BSTR Character, long CursorMode )
7057|{
7058|  HRESULT  hr;
7059|
7060|  /* 右タップしたときの処理 */
7061|  /* 右ドラッグを開始したときの処理 */
7062|  if ( Id == ISG_RightTap || Id == ISG_RightDrag ) {
7063|    IInkDrawingAttributes*  attr;
7064|
7065|    /* ストロークを描画しないようにする */
7066|    hr = m_InkOverlay->put_DynamicRendering( VARIANT_FALSE );
7067|    if ( hr != 0 )  error();
7068|
7069|    /* カーソルを描画しないようにする */
7070|    hr = m_DrawingStroke->get_DrawingAttributes( &attr );
7071|    if ( hr != 0 )  error();
7072|
7073|    hr = attr->put_RasterOperation( IRO_NoOperation );
7074|    if ( hr != 0 )  error();
7075|
7076|    hr = m_DrawingStroke->putref_DrawingAttributes( attr );
7077|    if ( hr != 0 )  error();
7078|
7079|    hr = attr->Release();  attr = NULL;
7080|
7081|    Invalidate( TRUE );
7082|
7083|    m_DrawingStroke = NULL;
7084|    m_bRightTap = true;
7085|
7086|    /* 続きは、OnStroke へ */
7087|  }
7088|}
7089|
7090|
7091| 
7092|/***********************************************************************
7093|  50. <<< [CChildView::OnStrokesDeleting] インクが消されようとしているときの処理 >>> 
7094|【補足】
7095|・消しゴムツールを使っているときだけ呼び出されます。
7096|************************************************************************/
7097|void  CChildView::OnStrokesDeleting( IInkStrokes* strokes )
7098|{
7099|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
7100|  IInkDisp*  ink;
7101|  HRESULT  hr;
7102|
7103|  hr = strokes->get_Ink( &ink );  if ( hr != 0 )  error();
7104|
7105|  app->m_UndoBuf->AllocNewStep_Ink2( Undo_Ink_Del, ink, strokes,
7106|    true, app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
7107|
7108|  hr = ink->Release();  ink = NULL;
7109|}
7110|
7111|
7112| 
7113|/***********************************************************************
7114|  51. <<< [CChildView::IsHitSelectedInk] 選択中のインクにヒットするかどうかを返す >>> 
7115|************************************************************************/
7116|bool  CChildView::IsHitSelectedInk( long x, long y )
7117|{
7118|  HRESULT  hr;
7119|  IInkDisp*  ink;
7120|  IInkRectangle*  rect;
7121|  RECT rectX;
7122|  IInkRenderer* render;
7123|  IInkStrokes*  hitStrokes;
7124|  long  iHit, iHold, nHit, nHold, hit_id, hold_id;
7125|  IInkStrokeDisp*  stroke;
7126|  POINT  pt;
7127|
7128|  if ( m_HoldStrokes == NULL )  return  false;
7129|
7130|  CClientDC  dc( this );
7131|
7132|  /* キャンバス座標からクライアント座標へ変換する */
7133|  x = x * m_Zoom / 100;  y = y * m_Zoom / 100;
7134|  pt = GetScrollPosition();
7135|  x -= pt.x;  y -= pt.y;
7136|
7137|  hr = m_InkOverlay->get_Renderer( &render );
7138|  if ( hr != 0 ) error();
7139|  hr = m_InkOverlay->get_Ink( &ink );
7140|  if ( hr != 0 )  error();
7141|
7142|  hr = render->PixelToInkSpace( (long)dc.m_hDC, &x, &y );
7143|  if ( hr != 0 )  error();
7144|
7145|  rectX.left = x - 260;  rectX.top = y - 260;
7146|  rectX.right = x + 260;  rectX.bottom = y + 260;
7147|  hr = CoCreateInstance( CLSID_InkRectangle, NULL, CLSCTX_INPROC_SERVER,
7148|                         IID_IInkRectangle, (void**)&rect );
7149|  if ( hr != 0 )  error();
7150|  hr = rect->put_Data( rectX );
7151|  if ( hr != 0 )  error();
7152|
7153|  hr = ink->HitTestWithRectangle( rect, 0.0f, &hitStrokes );
7154|  if ( hr != 0 )  error();
7155|
7156|  /* ヒットしたものが選択中か調べる */
7157|  hr = hitStrokes->get_Count( &nHit );
7158|  if ( hr != 0 )  error();
7159|  hr = m_HoldStrokes->get_Count( &nHold );
7160|  if ( hr != 0 )  error();
7161|
7162|  for ( iHit = 0; iHit < nHit; iHit++ ) {
7163|    hr = hitStrokes->Item( iHit, &stroke );
7164|    if ( hr != 0 )  error();
7165|    hr = stroke->get_ID( &hit_id );
7166|    if ( hr != 0 )  error();
7167|    stroke->Release();  stroke = NULL;
7168|
7169|    for ( iHold = 0; iHold < nHold; iHold++ ) {
7170|      hr = m_HoldStrokes->Item( iHold, &stroke );
7171|      if ( hr != 0 )  error();
7172|      hr = stroke->get_ID( &hold_id );
7173|      if ( hr != 0 )  error();
7174|      stroke->Release();  stroke = NULL;
7175|
7176|      if ( hold_id == hit_id )  goto exit_for;
7177|    }
7178|  }
7179|exit_for:
7180|
7181|  hitStrokes->Release();  hitStrokes = NULL;
7182|  hr = rect->Release();  rect = NULL;
7183|  hr = ink->Release();  ink = NULL;
7184|  hr = render->Release();  render = NULL;
7185|
7186|  return  nHit > 0 && hold_id == hit_id;
7187|}
7188|
7189|
7190| 
7191|/***********************************************************************
7192|  52. <<< [CChildView::SyncHoldStrokes] インクの選択状態を Ink コントロールに設定する >>> 
7193|【補足】
7194|・m_HoldStrokes を設定してから呼び出してください。
7195|************************************************************************/
7196|void  CChildView::SyncHoldStrokes()
7197|{
7198|  IInkRectangle*  rect;
7199|  IInkStrokes*  zero;
7200|  IInkDisp*  ink;
7201|  HRESULT  hr;
7202|
7203|  if ( m_InkOverlay == NULL )  return;
7204|
7205|  hr = m_InkOverlay->get_Ink( &ink );
7206|  if ( hr != 0 )  error();
7207|
7208|  hr = CoCreateInstance( CLSID_InkRectangle, NULL, CLSCTX_INPROC_SERVER,
7209|                         IID_IInkRectangle, (void**)&rect );
7210|  if ( hr != 0 )  error();
7211|
7212|  hr = rect->SetRectangle( 0, 0, 1, 1 );
7213|  if ( hr != 0 )  error();
7214|
7215|  hr = ink->HitTestWithRectangle( rect, 1, &zero );
7216|  if ( hr != 0 )  error();
7217|
7218|  hr = m_InkOverlay->put_Selection( m_HoldStrokes );
7219|  if ( hr != 0 )  error();
7220|
7221|  rect->Release();  rect = NULL;
7222|  zero->Release();  zero = NULL;
7223|  ink->Release();  ink = NULL;
7224|
7225|  SetResizeHandle();
7226|}
7227|
7228|
7229| 
7230|/***********************************************************************
7231|  53. <<< [CChildView::SelectInkToEmpty] インクの選択状態を解除する >>> 
7232|************************************************************************/
7233|void CChildView::SelectInkToEmpty()
7234|{
7235|  IInkRectangle*  rect;
7236|  IInkStrokes*  zero;
7237|  IInkDisp*  ink;
7238|  HRESULT  hr;
7239|
7240|  if ( m_InkOverlay == NULL )  return;
7241|
7242|  hr = m_InkOverlay->get_Ink( &ink );
7243|  if ( hr != 0 )  error();
7244|
7245|  hr = CoCreateInstance( CLSID_InkRectangle, NULL, CLSCTX_INPROC_SERVER,
7246|                         IID_IInkRectangle, (void**)&rect );
7247|  if ( hr != 0 )  error();
7248|
7249|  hr = rect->SetRectangle( 0, 0, 1, 1 );
7250|  if ( hr != 0 )  error();
7251|
7252|  hr = ink->HitTestWithRectangle( rect, 1, &zero );
7253|  if ( hr != 0 )  error();
7254|
7255|  hr = m_InkOverlay->put_Selection( zero );
7256|  if ( hr != 0 )  error();
7257|
7258|  rect->Release();  rect = NULL;
7259|  zero->Release();  zero = NULL;
7260|  ink->Release();  ink = NULL;
7261|
7262|  if ( m_HoldStrokes != NULL )  { hr = m_HoldStrokes->Release();  m_HoldStrokes = NULL; }
7263|}
7264|
7265|
7266| 
7267|/***********************************************************************
7268|  54. <<< [CChildView::GetStrokeCount] インクのストロークの数を返す >>> 
7269|************************************************************************/
7270|int  CChildView::GetStrokeCount()
7271|{
7272|  HRESULT  hr;
7273|  IInkStrokes*  strokes;
7274|  IInkDisp*  ink;
7275|  long  n;
7276|
7277|  if ( m_InkOverlay == NULL )  return  0;
7278|
7279|  hr = m_InkOverlay->get_Ink( &ink );
7280|  if ( hr != 0 )  error();
7281|
7282|  hr = ink->get_Strokes( &strokes );
7283|  if ( hr != 0 )  error();
7284|
7285|  hr = strokes->get_Count( &n );
7286|  if ( hr != 0 )  error();
7287|
7288|  strokes->Release();  strokes = NULL;
7289|  ink->Release();  ink = NULL;
7290|
7291|  return  n;
7292|}
7293|
7294|
7295| 
7296|/***********************************************************************
7297|  55. <<< [CChildView::GetSelectedStrokeCount] 選択中のインクのストロークの数を返す >>> 
7298|************************************************************************/
7299|int  CChildView::GetSelectedStrokeCount()
7300|{
7301|  HRESULT  hr;
7302|  IInkStrokes*  selection;
7303|  IInkDisp*  ink;
7304|  long  n;
7305|
7306|  if ( m_InkOverlay == NULL )  return  0;
7307|
7308|  hr = m_InkOverlay->get_Ink( &ink );
7309|  if ( hr != 0 )  error();
7310|
7311|  hr = m_InkOverlay->get_Selection( &selection );
7312|  if ( hr != 0 )  error();
7313|
7314|  hr = selection->get_Count( &n );
7315|  if ( hr != 0 )  error();
7316|
7317|  selection->Release();  selection = NULL;
7318|  ink->Release();  ink = NULL;
7319|
7320|  return  n;
7321|}
7322|
7323|
7324| 
7325|/***********************************************************************
7326|  56. <<< [CChildView::SetResizeHandle] インクのリサイズ・ハンドルの位置を設定する >>> 
7327|【補足】
7328|・m_HoldStrokes を元に m_InkResizeHandlePos を設定します。
7329|************************************************************************/
7330|void  CChildView::SetResizeHandle()
7331|{
7332|  HRESULT  hr;
7333|  IInkRenderer* render;
7334|  IInkRectangle*  rect;
7335|  RECT rectX;
7336|  CClientDC  dc( this );
7337|  POINT  pt;
7338|
7339|  hr = m_InkOverlay->get_Renderer( &render );
7340|  if ( hr != 0 ) error();
7341|
7342|  hr = m_HoldStrokes->GetBoundingBox( IBBM_Default, &rect );
7343|  if ( hr != 0 )  error();
7344|  hr = rect->get_Data( &rectX );
7345|  if ( hr != 0 )  error();
7346|
7347|  m_InkResizeHandlePos.x = rectX.right;
7348|  m_InkResizeHandlePos.y = rectX.bottom;
7349|
7350|  hr = render->InkSpaceToPixel( (long)dc.m_hDC,
7351|    &m_InkResizeHandlePos.x, &m_InkResizeHandlePos.y );
7352|  if ( hr != 0 )  error();
7353|  m_InkResizeHandlePos.x += 4;
7354|  m_InkResizeHandlePos.y += 4;
7355|
7356|  pt = GetScrollPosition();
7357|  m_InkResizeHandlePos.x += pt.x;
7358|  m_InkResizeHandlePos.y += pt.y;
7359|
7360|  m_InkResizeHandlePos.x = m_InkResizeHandlePos.x * 100 / m_Zoom;
7361|  m_InkResizeHandlePos.y = m_InkResizeHandlePos.y * 100 / m_Zoom;
7362|
7363|  hr = rect->Release();  rect = NULL;
7364|  hr = render->Release();  render = NULL;
7365|}
7366| 
7367|/***********************************************************************
7368|  57. <<< [CChildView::DuplicateStrokes] インクの参照集合を複製する >>> 
7369|【補足】
7370|・IInkDisp::ExtractStrokes が使えると思ったが、複製したものは Ink になって
7371|  しまうため、この関数を用意した。
7372|************************************************************************/
7373|IInkStrokes*  CChildView::DuplicateStrokes( IInkStrokes* src )
7374|{
7375|  HRESULT  hr;
7376|  IInkDisp*  ink;
7377|  IInkStrokeDisp*  stroke1;
7378|  IInkStrokeDisp*  stroke2;
7379|  IInkStrokes*  dst;
7380|  long  i1, i2, id1, id2, nSrc, nStrokes;
7381|
7382|  hr = m_InkOverlay->get_Ink( &ink ); if ( hr != 0 )  error();
7383|  hr = ink->get_Strokes( &dst ); if ( hr != 0 )  error();
7384|  hr = src->get_Count( &nSrc ); if ( hr != 0 )  error();
7385|  hr = dst->get_Count( &nStrokes ); if ( hr != 0 )  error();
7386|  for ( i1 = 0; i1 < nStrokes; i1++ ) {
7387|    hr = dst->Item( i1, &stroke1 ); if ( hr != 0 )  error();
7388|    hr = stroke1->get_ID( &id1 ); if ( hr != 0 )  error();
7389|    for ( i2 = 0; i2 < nSrc; i2++ ) {
7390|      hr = src->Item( i2, &stroke2 ); if ( hr != 0 )  error();
7391|      hr = stroke2->get_ID( &id2 ); if ( hr != 0 )  error();
7392|      hr = stroke2->Release();  stroke2 = NULL;
7393|      if ( id1 == id2 )  break;
7394|    }
7395|    if ( id1 != id2 )
7396|      { dst->Remove( stroke1 );  i1--;  nStrokes--; }
7397|    hr = stroke1->Release();  stroke1 = NULL;
7398|  }
7399|  hr = ink->Release();  ink = NULL;
7400|
7401|  return  dst;
7402|}
7403| 
7404|/***********************************************************************
7405|  58. <<< [CChildView::DebugDrawStrokes] 指定のストロークのみを表示する(デバッグ用) >>> 
7406|************************************************************************/
7407|#ifndef  NDEBUG
7408|void  CChildView::DebugDrawStrokes( IInkStrokes* strokes )
7409|{
7410|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
7411|  CPoint  pt = GetScrollPosition();
7412|  HRESULT  hr;
7413|  RECT  rect;
7414|  IInkRenderer* render;
7415|  long  x, y;
7416|  int  w = app->m_file.m_Canvas.m_Width * m_Zoom / 100 - pt.x;
7417|  int  h = app->m_file.m_Canvas.m_Height * m_Zoom / 100 - pt.y;
7418|  float xf, yf;
7419|  CadPrim_DrawParam  p;
7420|  CClientDC  dc( this );
7421|  #ifndef NDEBUG
7422|    int  nInk = GetInkCount();
7423|  #endif
7424|
7425|  hr = m_InkOverlay->get_Renderer( &render );
7426|  if ( hr != 0 ) error();
7427|
7428|
7429|  /* クリアする */
7430|  GetDrawParam( &p );  p.bWhiteToBGColor = (app->m_bBackTransparent != 0);
7431|  app->m_file.m_Canvas.Draw( &m_BitmapDC, &p );
7432|
7433|
7434|  /* 座標系を変換する */
7435|  if ( pt != m_prevScrollPos || m_Zoom != m_prevZoom ) {
7436|         /* 座標系をかえると図形とインクの再描画の無限ループになってしまう */
7437|
7438|    if ( m_prevX0 != 0 || m_prevY0 != 0 ) {
7439|      hr = render->Move( m_prevX0, m_prevY0 );  /* PixelToInkSpace の基準座標を戻す */
7440|      if ( hr != 0 ) error();
7441|    }
7442|
7443|    if ( m_Zoom != m_prevZoom ) {
7444|      hr = render->ScaleTransform( (float)m_Zoom / m_prevZoom, (float)m_Zoom / m_prevZoom );
7445|      if ( hr != 0 ) error();
7446|      m_prevZoom = m_Zoom;
7447|    }
7448|
7449|    x = pt.x;  y = pt.y;
7450|    hr = render->PixelToInkSpace( (long)m_BitmapDC.m_hDC, &x, &y );
7451|    if ( hr != 0 ) error();
7452|    xf = (float)x * m_Zoom / 100;  yf = (float)y * m_Zoom / 100;
7453|    m_prevScrollPos = pt;
7454|
7455|    m_prevX0 = xf;  m_prevY0 = yf;
7456|    if ( m_prevX0 != 0 || m_prevY0 != 0 ) {
7457|      hr = render->Move( -m_prevX0, -m_prevY0 );
7458|      if ( hr != 0 ) error();
7459|    }
7460|  }
7461|
7462|  /* 描画する */
7463|  hr = render->Draw( (long)m_BitmapDC.m_hDC, strokes );
7464|  if ( hr != 0 ) error();
7465|
7466|  GetClientRect( &rect );
7467|  if ( w > rect.right )  w = rect.right;
7468|  if ( h > rect.bottom )  h = rect.bottom;
7469|
7470|  dc.BitBlt( 0, 0, w, h, &m_BitmapDC, 0, 0, SRCCOPY );
7471|
7472|  render->Release();  render = NULL;
7473|
7474|  ASSERT( nInk == GetInkCount() );
7475|}
7476|#endif
7477|
7478|
7479| 
7480|/***********************************************************************
7481|  59. <<< [CChildView::DebugPrintStrokes] 指定のストロークの座標をデバッグ表示する >>> 
7482|************************************************************************/
7483|#ifndef  NDEBUG
7484|void  CChildView::DebugPrintStrokes( IInkStrokes* strokes )
7485|{
7486|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
7487|  HRESULT  hr;
7488|  long  x, y, x0, y0, w = 22;
7489|  int  iStroke;
7490|  IInkStrokeDisp*  stroke;
7491|  IInkRenderer*  rend;
7492|  VARIANT  points;
7493|  VARIANT  pressureName;
7494|  long  i;
7495|  long  n;
7496|  enum InkPenTip  tip;
7497|  InkRasterOperation  ras;
7498|  float  baseW;
7499|  VARIANT  weights;
7500|  VARIANT_BOOL  bPress;
7501|  VARIANT_BOOL  bIgnorePress;
7502|  #ifndef NDEBUG
7503|    int  nInk = GetInkCount();
7504|  #endif
7505|
7506|  Errors_startPool();
7507|
7508|  Variant_initEmpty( &points );
7509|  Variant_initEmpty( &weights );
7510|  Variant_initBSTR( &pressureName, STR_GUID_NORMALPRESSURE );
7511|
7512|  hr = m_InkOverlay->get_Renderer( &rend );
7513|  if ( hr != 0 )  error();
7514|  hr = rend->ScaleTransform( (float)100 / m_Zoom, (float)100 / m_Zoom );
7515|  if ( hr != 0 ) error();
7516|
7517|  for ( iStroke = 0; ; iStroke ++ ) {
7518|    strokes->Item( iStroke, &stroke );
7519|    if ( stroke == NULL )  break;
7520|
7521|    hr = stroke->GetPoints ( 0, -1, &points );
7522|    if ( hr == TPC_E_INVALID_STROKE )  continue;
7523|    if ( hr != S_OK )  { WD( hr );  error(); }
7524|
7525|    SafeArrayGetLBound( points.parray, 1, &x );
7526|    SafeArrayGetUBound( points.parray, 1, &y );
7527|    n = (y - x + 1) / 2;
7528|
7529|    /* ストロークの描画属性を取得する */
7530|    hr = stroke->GetPacketValuesByProperty( Variant_refBSTR( &pressureName ), 0, -1, &weights );
7531|    if ( hr == S_OK )  bPress = true;
7532|    else if ( hr == E_INVALIDARG )  bPress = false;
7533|    else  error();
7534|    hr = stroke->get_DrawingAttributes( &m_WorkDrawAttr );
7535|    if ( hr != 0 )  error();
7536|    hr = m_WorkDrawAttr->get_Color( &i );
7537|    if ( hr != 0 )  error();
7538|    hr = m_YellowMarkerAttr->get_PenTip( &tip );
7539|    if ( hr != 0 )  error();
7540|    if ( tip == IPT_Rectangle )  hr = m_WorkDrawAttr->get_Height( &baseW );
7541|    else  hr = m_WorkDrawAttr->get_Width( &baseW );
7542|    if ( hr != 0 )  error();
7543|    hr = m_WorkDrawAttr->get_IgnorePressure( &bIgnorePress );
7544|    if ( hr != 0 )  error();
7545|    hr = m_WorkDrawAttr->get_RasterOperation( &ras );
7546|    if ( hr != 0 )  error();
7547|
7548|    Errors_printf( "<g id=\"svgcats-stroke\" style=\"stroke:rgb(%d,%d,%d);stroke-linecap:%s\">",
7549|      Color_WinRGB_getR( i ), Color_WinRGB_getG( i ), Color_WinRGB_getB( i ),
7550|      "round" /*tip == IPT_Rectangle ? "butt" : "round"*/  /* butt では線の間ができてしまう */
7551|    );
7552|
7553|    w = 17 * (long)baseW / 53;
7554|
7555|    for ( i = 0; i < n*2; i+=2 ) {
7556|
7557|      /* 座標を取得する */
7558|      SafeArrayGetElement( points.parray, &i, &x );
7559|      i++;
7560|      SafeArrayGetElement( points.parray, &i, &y );
7561|      i--;
7562|      x *= 10;  y *= 10;
7563|      rend->InkSpaceToPixel( (long)m_BitmapDC.m_hDC, &x, &y );
7564|
7565|      /* 太さを取得する */
7566|      if ( bPress && ! bIgnorePress ) {
7567|        i /= 2;
7568|        SafeArrayGetElement( weights.parray, &i, &w );
7569|        i *= 2;
7570|        w = (long)( w * baseW / 310 );
7571|      }
7572|
7573|      /* SVG ファイルに出力する */
7574|      if ( i != 0 ) {
7575|        Errors_printf( "<line x1=\"%d.%d\" y1=\"%d.%d\" x2=\"%d.%d\" y2=\"%d.%d\"",
7576|          x0 / 10, x0 % 10, y0 / 10, y0 % 10, x / 10, x % 10, y / 10, y % 10 );
7577|
7578|        Errors_printf( "\tstyle=\"stroke-width:%d.%d\"/>", w/10, w%10 );
7579|
7580|        x0 = ( x < x0 ) ? x+3 : x-3;
7581|        y0 = ( y < y0 ) ? y+3 : y-3;
7582|      }
7583|      else {
7584|        x0 = x;
7585|        y0 = y;
7586|      }
7587|    }
7588|
7589|    hr = m_WorkDrawAttr->Release();  m_WorkDrawAttr = NULL;
7590|    if ( hr > 5 )  error();
7591|    hr = stroke->Release();  stroke = NULL;
7592|    if ( hr > 5 )  error();
7593|    Variant_finish( &weights );
7594|    Variant_finish( &points );
7595|  }
7596|  Variant_finish( &pressureName );
7597|
7598|  hr = rend->ScaleTransform( (float)m_Zoom / 100, (float)m_Zoom / 100 );
7599|  if ( hr != 0 ) error();
7600|  hr = rend->Move( -m_prevX0, -m_prevY0 );
7601|  if ( hr != 0 ) error();
7602|
7603|  Variant_finish( &points );
7604|  Variant_finish( &weights );
7605|
7606|  Errors_endPool();
7607|
7608|  ASSERT( nInk == GetInkCount() );
7609|}
7610|#endif
7611|
7612|
7613| 
7614|/***********************************************************************
7615|  60. <<< [CChildView::OnEditUndo] アンドゥする >>> 
7616|************************************************************************/
7617|#if  ERRORS_DEBUG_FALSE
7618|  #define  UNDO_REDO_TRACE
7619|#endif
7620|
7621|void CChildView::OnEditUndo()
7622|{
7623|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
7624|  CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
7625|  ListX_ElemX*  p;
7626|  ListX_ElemX*  p2;
7627|  Canvas  prevCanvas;
7628|  ListX*  targetPrims;
7629|  HRESULT  hr;
7630|  IInkDisp*  ink;
7631|  IInkRenderer* render;
7632|  int  iCurrentPage = app->m_file.m_CurrentPageNum;
7633|  int  iNextPage;
7634|
7635|  if ( ! app->m_UndoBuf->IsAbleUndo() )  return;
7636|
7637|  CWaitCursor  wa;
7638|
7639|  #ifdef  UNDO_REDO_TRACE
7640|    Errors_startPool();
7641|    app->printPrims( &app->m_file.m_prims, "1" );
7642|  #endif
7643|
7644|  OnFinishPrimMove();
7645|  prevCanvas.copy( &app->m_file.m_Canvas, &app->m_file.m_prims );
7646|  app->ChgPage( &app->m_file, iCurrentPage );
7647|
7648|
7649|  /* アンドゥするページを一瞬表示する */
7650|  iNextPage = app->m_UndoBuf->GetNextUndoPageNum();
7651|  if ( iNextPage != iCurrentPage && iNextPage != -1 ) {
7652|    m_bBitmap = false;
7653|
7654|    if ( iNextPage == 0 && app->m_file.m_StartPageNum == 0 &&
7655|         iCurrentPage != 0 &&
7656|         SVGCat_File_getMaxPageNum( &app->m_file ) == 1 ) {
7657|      MessageBox( "元に戻す(アンドゥする)背景ページに移動します。", "SVG Cats", MB_OK );
7658|    }
7659|
7660|    frame->ChgPage( iNextPage );
7661|    Redraw( true );
7662|    Sleep(300);
7663|  }
7664|
7665|
7666|  /* アンドゥする */
7667|  if ( m_InkOverlay != NULL ) {
7668|    hr = m_InkOverlay->get_Ink( &ink );  if ( hr != 0 )  error();
7669|    if ( m_Zoom != 100 ) {
7670|      hr = m_InkOverlay->get_Renderer( &render ); if ( hr != 0 ) error();
7671|      hr = render->ScaleTransform( (float)100 / m_Zoom, (float)100 / m_Zoom );
7672|      if ( hr != 0 ) error();  /* 100%に戻さないと IInkStrokes::Move が影響するため */
7673|    }
7674|  }
7675|  else  ink = NULL;
7676|
7677|  targetPrims = app->m_UndoBuf->Undo( frame, ink );
7678|
7679|  if ( ink != NULL )  {
7680|    if ( m_Zoom != 100 ) {
7681|      hr = render->ScaleTransform( (float)m_Zoom / 100, (float)m_Zoom / 100 );
7682|      if ( hr != 0 ) error();
7683|      render->Release();  render = NULL;
7684|    }
7685|    hr = ink->Release();  ink = NULL;
7686|  }
7687|
7688|
7689|  /* アンドゥした対象を選択状態にする */
7690|  ListX_toEmptyDelete( &m_MultiHolds, ListX_ElemX, NULL );
7691|  m_HoldPrim = NULL;
7692|
7693|  for ( ListX_forEach( &app->m_UndoBuf->m_holds, &p, ListX_ElemX ) ) {
7694|    p2 = ListX_addLastMalloc( &m_MultiHolds, ListX_ElemX );
7695|    p2->p = p->p;
7696|  }
7697|  p = ListX_getFirst( &app->m_UndoBuf->m_holds, ListX_ElemX );
7698|  m_HoldPrim = ( p == NULL ? NULL : (CadPrim*)p->p );
7699|
7700|  #ifdef  UNDO_REDO_TRACE
7701|    app->printPrims( &app->m_file.m_prims, "2");
7702|  #endif
7703|
7704|  SetMultiSelect();
7705|  for ( ListX_forEach( &app->m_file.m_prims, &p, ListX_ElemX ) )
7706|    ((CadPrim*)p->p)->SetHold( false );
7707|  for ( ListX_forEach( &app->m_UndoBuf->m_holds, &p, ListX_ElemX ) )
7708|    ((CadPrim*)p->p)->SetHold( true );
7709|
7710|  if ( m_InkOverlay != NULL ) {
7711|    if ( m_HoldStrokes != NULL )  { m_HoldStrokes->Release();  m_HoldStrokes = NULL; }
7712|    if ( app->m_UndoBuf->m_holdStrokes != NULL ) {
7713|      m_HoldStrokes = DuplicateStrokes( app->m_UndoBuf->m_holdStrokes );
7714|      SetResizeHandle();
7715|    }
7716|  }
7717|
7718|
7719|  /* アンドゥした結果を表示する */
7720|  if ( prevCanvas.isEqual( &app->m_file.m_Canvas ) )
7721|    Redraw( false );
7722|  else {
7723|    m_bBitmap = false;
7724|    Invalidate( FALSE );
7725|  }
7726|
7727|  frame->UpdateWindowText();
7728|  frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
7729|  SetCursor( NULL );
7730|
7731|  #ifdef  UNDO_REDO_TRACE
7732|    app->printPrims( &app->m_file.m_prims, "9");
7733|    Errors_endPool();
7734|  #endif
7735|}
7736|
7737|
7738| 
7739|/***********************************************************************
7740|  61. <<< [CChildView::OnEditRedo] リドゥする >>> 
7741|************************************************************************/
7742|void CChildView::OnEditRedo()
7743|{
7744|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
7745|  CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
7746|  ListX_ElemX*  p;
7747|  ListX_ElemX*  p2;
7748|  Canvas  prevCanvas;
7749|  ListX*  targetPrims;
7750|  HRESULT  hr;
7751|  IInkDisp*  ink;
7752|  int  iCurrentPage = app->m_file.m_CurrentPageNum;
7753|  int  iNextPage;
7754|
7755|  if ( ! app->m_UndoBuf->IsAbleRedo() )  return;
7756|
7757|  CWaitCursor  wa;
7758|
7759|  #ifdef  UNDO_REDO_TRACE
7760|    Errors_startPool();
7761|    app->printPrims( &app->m_file.m_prims, "1");
7762|  #endif
7763|
7764|  OnFinishPrimMove();
7765|  prevCanvas.copy( &app->m_file.m_Canvas, &app->m_file.m_prims );
7766|  app->ChgPage( &app->m_file, iCurrentPage );
7767|
7768|  /* リドゥするページを一瞬表示する */
7769|  iNextPage = app->m_UndoBuf->GetNextRedoPageNum();
7770|  if ( iNextPage != iCurrentPage && iNextPage != -1 ) {
7771|    m_bBitmap = false;
7772|
7773|    if ( iNextPage == 0 && app->m_file.m_StartPageNum == 0 &&
7774|         iCurrentPage != 0 &&
7775|         SVGCat_File_getMaxPageNum( &app->m_file ) == 1 ) {
7776|      MessageBox( "進む(リドゥ)を行う背景ページに移動します。", "SVG Cats", MB_OK );
7777|    }
7778|
7779|    frame->ChgPage( iNextPage );
7780|    Redraw( true );
7781|    Sleep(300);
7782|  }
7783|
7784|
7785|  /* リドゥする */
7786|  if ( m_InkOverlay != NULL )
7787|    { hr = m_InkOverlay->get_Ink( &ink );  if ( hr != 0 )  error(); }
7788|  else  ink = NULL;
7789|
7790|  targetPrims = app->m_UndoBuf->Redo( frame, ink );
7791|
7792|  if ( ink != NULL )  { hr = ink->Release();  ink = NULL; }
7793|
7794|
7795|  /* リドゥした対象を選択状態にする */
7796|  ListX_toEmptyDelete( &m_MultiHolds, ListX_ElemX, NULL );
7797|  m_HoldPrim = NULL;
7798|
7799|  for ( ListX_forEach( &app->m_UndoBuf->m_holds, &p, ListX_ElemX ) ) {
7800|    p2 = ListX_addLastMalloc( &m_MultiHolds, ListX_ElemX );
7801|    p2->p = p->p;
7802|  }
7803|  p = ListX_getFirst( &app->m_UndoBuf->m_holds, ListX_ElemX );
7804|  m_HoldPrim = ( p == NULL ? NULL : (CadPrim*)p->p );
7805|  if ( m_HoldPrim != NULL )  m_HoldPrim->SetHold( true );
7806|
7807|  #ifdef  UNDO_REDO_TRACE
7808|    app->printPrims( &app->m_file.m_prims, "2");
7809|  #endif
7810|
7811|  SetMultiSelect();
7812|  for ( ListX_forEach( &app->m_file.m_prims, &p, ListX_ElemX ) )
7813|    ((CadPrim*)p->p)->SetHold( false );
7814|  for ( ListX_forEach( &app->m_UndoBuf->m_holds, &p, ListX_ElemX ) )
7815|    ((CadPrim*)p->p)->SetHold( true );
7816|
7817|  if ( m_InkOverlay != NULL ) {
7818|    if ( m_HoldStrokes != NULL )  { m_HoldStrokes->Release();  m_HoldStrokes = NULL; }
7819|    if ( app->m_UndoBuf->m_holdStrokes != NULL ) {
7820|      m_HoldStrokes = DuplicateStrokes( app->m_UndoBuf->m_holdStrokes );
7821|      hr = m_InkOverlay->put_Selection( m_HoldStrokes );  if ( hr != 0 )  error();
7822|      SetResizeHandle();
7823|    }
7824|  }
7825|
7826|
7827|  /* リドゥした結果を表示する */
7828|  if ( prevCanvas.isEqual( &app->m_file.m_Canvas ) )
7829|    Redraw( false );
7830|  else {
7831|    m_bBitmap = false;
7832|    Invalidate( FALSE );
7833|  }
7834|
7835|  frame->UpdateWindowText();
7836|  frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
7837|  SetCursor( NULL );
7838|
7839|  #ifdef  UNDO_REDO_TRACE
7840|    app->printPrims( &app->m_file.m_prims, "9");
7841|    Errors_endPool();
7842|  #endif
7843|}
7844|
7845|
7846| 
7847|/***********************************************************************
7848|  62. <<< [CChildView::ResetSelect] 非選択状態にする >>> 
7849|************************************************************************/
7850|void  CChildView::ResetSelect( bool bUpdatePropBox )
7851|{
7852|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
7853|  CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
7854|  ListX_ElemX*  p;
7855|  int  bEmpty = true;
7856|
7857|  if ( !( ListX_isEmpty( &m_MultiHolds ) && ListX_isEmpty( &m_MultiSelects ) &&
7858|          ListX_isEmpty( &m_MultiBefore ) && m_BeforePrim == NULL ) ) {
7859|    SelectInkToEmpty();
7860|
7861|    ListX_toEmptyDelete( &m_MultiHolds, ListX_ElemX, NULL );
7862|    m_HoldPrim = NULL;
7863|    ListX_toEmptyDelete( &m_MultiSelects, ListX_ElemX, NULL );
7864|    for ( ListX_forEach( &m_MultiBefore, &p, ListX_ElemX ) )
7865|      delete  (CadPrim*)p->p;
7866|    ListX_toEmptyDelete( &m_MultiBefore, ListX_ElemX, NULL );
7867|    if ( m_BeforePrim != NULL )  delete  m_BeforePrim;
7868|    m_BeforePrim = NULL;
7869|
7870|    for ( ListX_forEach( &app->m_file.m_prims, &p, ListX_ElemX ) ) {
7871|      ((CadPrim*)p->p)->SetHold( false );
7872|      ((CadPrim*)p->p)->SetSelected( false );
7873|    }
7874|    bEmpty = false;
7875|  }
7876|
7877|  if ( m_HoldStrokes != NULL ) {
7878|    m_HoldStrokes->Release();  m_HoldStrokes = NULL;
7879|    bEmpty = false;
7880|  }
7881|
7882|  if ( bUpdatePropBox )
7883|    frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
7884|
7885|  if ( ! bEmpty )  Redraw( false );
7886|}
7887|
7888|
7889| 
7890|/***********************************************************************
7891|  63. <<< [CChildView::OnSelectAll] すべて選択状態にする >>> 
7892|************************************************************************/
7893|void CChildView::OnSelectAll()
7894|{
7895|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
7896|  CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
7897|  ListX_ElemX*  p;
7898|  ListX_ElemX*  p2;
7899|  IInkDisp*  ink;
7900|  IInkStrokes*  strokes;
7901|  HRESULT  hr;
7902|
7903|
7904|  ResetSelect();  /* OnSelect ResetSelect しないケースがあるので必要 */
7905|  frame->OnSelect();
7906|
7907|
7908|  /* 図形を全て選択する */
7909|  m_HoldPrim = NULL;
7910|  for ( ListX_forEach( &app->m_file.m_prims, &p, ListX_ElemX ) ) {
7911|    p2 = ListX_addLastMalloc( &m_MultiHolds, ListX_ElemX );
7912|    p2->p = p->p;
7913|    ((CadPrim*)p->p)->SetHold( true );
7914|
7915|    m_HoldPrim = (CadPrim*)p->p;
7916|  }
7917|  for ( p = ListX_getFirst( &m_MultiHolds, ListX_ElemX ); p != NULL; ) {
7918|    if ( ! ((CadPrim*)p->p)->IsHoldable() ) {
7919|      ((CadPrim*)p->p)->SetHold( false );
7920|      p2 = ListX_Elem_getNextT( p, ListX_ElemX );
7921|      if ( p->p == m_HoldPrim )  m_HoldPrim = NULL;
7922|      ListX_removeFree( &m_MultiHolds, p );
7923|      p = p2;
7924|    }
7925|    else
7926|      p = ListX_Elem_getNextT( p, ListX_ElemX );
7927|  }
7928|  if ( m_HoldPrim == NULL ) {
7929|    p2 = ListX_getFirst( &m_MultiHolds, ListX_ElemX );
7930|    m_HoldPrim = (CadPrim*)( p2 == NULL  ?  NULL : p2->p );
7931|  }
7932|  for ( ListX_forEach( &m_MultiHolds, &p, ListX_ElemX ) ) {
7933|    if ( (CadPrim*)p->p == m_HoldPrim ) {
7934|      ListX_remove( &m_MultiHolds, p );
7935|      ListX_addFirst( &m_MultiHolds, p );
7936|      break;
7937|    }
7938|  }
7939|  SetMultiSelect();
7940|
7941|
7942|  /* インクを全て選択する */
7943|  if ( m_InkOverlay != NULL ) {
7944|    hr = m_InkOverlay->get_Ink( &ink );  if ( hr != 0 )  error();
7945|    hr = ink->get_Strokes( &strokes );  if ( hr != 0 )  error();
7946|    m_HoldStrokes = DuplicateStrokes( strokes );
7947|    hr = m_InkOverlay->put_Selection( m_HoldStrokes );  if ( hr != 0 )  error();
7948|    SetResizeHandle();
7949|    hr = strokes->Release();  strokes = NULL;
7950|    hr = ink->Release();  strokes = NULL;
7951|  }
7952|
7953|  Redraw( false );
7954|  frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
7955|}
7956|
7957|
7958| 
7959|/***********************************************************************
7960|  64. <<< [CChildView::SetMultiSelect] m_MultiSelects を調節する >>> 
7961|【補足】
7962|・ラインの両端が Text_Box とリンクしているものも m_MultiSelects に含める。
7963|************************************************************************/
7964|void CChildView::SetMultiSelect()
7965|{
7966|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
7967|  ListX_ElemX*   p;
7968|  ListX_ElemX*   p2;
7969|
7970|  /* 選択状態をリセットする */
7971|  for ( ListX_forEach( &app->m_file.m_prims, &p, ListX_ElemX ) ) {
7972|    ((CadPrim*)p->p)->SetSelected( false );
7973|  }
7974|  ListX_toEmptyDelete( &m_MultiSelects, ListX_ElemX, NULL );
7975|
7976|  /* とりあえず MultiHolds はすべて含める */
7977|  for ( ListX_forEach( &m_MultiHolds, &p, ListX_ElemX ) ) {
7978|    p2 = ListX_addLastMalloc( &m_MultiSelects, ListX_ElemX );
7979|    p2->p = p->p;
7980|  }
7981|
7982|  for ( ListX_forEach( &m_MultiHolds, &p, ListX_ElemX ) ) {
7983|
7984|    switch ( ((CadPrim*)p->p)->GetTypeID() ) {
7985|
7986|      /* Text_Box にリンクしているラインについて調査する */
7987|      case  Text_Box_TypeID: {
7988|        Text_Box*  box = (Text_Box*)p->p;
7989|        CadPrim_Link*  link;
7990|
7991|        for ( ListX_forEach( &box->m_Links, &link, CadPrim_Link ) ) {
7992|          for ( ListX_forEach( &m_MultiSelects, &p2, ListX_ElemX ) ) {
7993|            if ( link->prim == (CadPrim*)p2->p )  break;
7994|          }
7995|
7996|          switch ( link->prim->GetTypeID() ) {
7997|
7998|            /* ラインの両端が TextBox とリンクしていないなら対象外とする */
7999|            case  Line_Ex_TypeID: {
8000|              Line_Ex*  line = (Line_Ex*)link->prim;
8001|              if ( line->m_Controler[0] == NULL ||
8002|                   ! line->m_Controler[0]->GetHold() )
8003|                continue;
8004|              if ( line->m_Controler[1] == NULL ||
8005|                   ! line->m_Controler[1]->GetHold() )
8006|                continue;
8007|              break;
8008|            }
8009|            case  Line_Corner_TypeID: {
8010|              Line_Corner*  line = (Line_Corner*)link->prim;
8011|              if ( line->m_Controler[0] == NULL ||
8012|                   ! line->m_Controler[0]->GetHold() )
8013|                continue;
8014|              if ( line->m_Controler[1] == NULL ||
8015|                   ! line->m_Controler[1]->GetHold() )
8016|                continue;
8017|              break;
8018|            }
8019|            default:  continue;
8020|          }
8021|          if ( p2 == NULL ) {
8022|            p2 = ListX_addLastMalloc( &m_MultiSelects, ListX_ElemX );
8023|            p2->p = link->prim;
8024|          }
8025|        }
8026|      }
8027|    }
8028|  }
8029|
8030|  /* 順番を Zオーダーに合わせる */
8031|  for ( ListX_forEach( &app->m_file.m_prims, &p, ListX_ElemX ) ) {
8032|    for ( ListX_forEach( &m_MultiSelects, &p2, ListX_ElemX ) ) {
8033|      if ( p2->p == p->p ) {
8034|        ListX_remove( &m_MultiSelects, p2 );
8035|        ListX_addLast( &m_MultiSelects, p2 );
8036|        break;
8037|      }
8038|    }
8039|  }
8040|
8041|  /* MultiSelects に含まれる図形を、Selected にする */
8042|  for ( ListX_forEach( &m_MultiSelects, &p, ListX_ElemX ) ) {
8043|    ((CadPrim*)p->p)->SetSelected( true );
8044|  }
8045|}
8046|
8047|
8048| 
8049|/***********************************************************************
8050|  65. <<< [CChildView::OnSetPropMulti] >>> 
8051|************************************************************************/
8052|void CChildView::OnSetPropMulti()
8053|{
8054|  CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
8055|
8056|  frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
8057|}
8058|
8059| 
8060|/***********************************************************************
8061|  66. <<< [CChildView::GetClipSize] クリップボードに格納するデータのサイズを返す >>> 
8062|【補足】
8063|・フォーマットは、CChildView::GetClipData を参照。
8064|************************************************************************/
8065|int  CChildView::GetClipSize( bool bPageCopy )
8066|{
8067|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
8068|  ListX_ElemX*  p;
8069|  int  size;
8070|
8071|  size = 0;
8072|  if ( bPageCopy ) {
8073|    char*  title = SVGCat_File_getCurrentPage( &app->m_file )->title;
8074|
8075|    size += ( strlen( title ) + 4 ) & ~3;
8076|    for ( ListX_forEach( &app->m_file.m_prims, &p, ListX_ElemX ) ) {
8077|      size += 2*sizeof(int) + ((CadPrim*)p->p)->GetSerializedSize();
8078|    }
8079|  }
8080|  else {
8081|    for ( ListX_forEach( &m_MultiSelects, &p, ListX_ElemX ) ) {
8082|      size += 2*sizeof(int) + ((CadPrim*)p->p)->GetSerializedSize();
8083|    }
8084|  }
8085|  size += ( 3 + (size > 0) ) * sizeof(int);
8086|
8087|  return  size;
8088|}
8089|
8090|
8091| 
8092|/***********************************************************************
8093|  67. <<< [CChildView::GetClipData] クリップボードに格納するデータを data に格納する >>> 
8094|【補足】
8095|・フォーマットは、次のとおり。
8096|  int 全体のデータサイズ;  int  flags;  int  n=図形の数;  int  複数選択の内の代表の図形番号;
8097|  ページコピーなら char[] ページタイトル; ただしサイズは4バイトアライン
8098|  図形ごとに { int データサイズ;  int タイプID;  char  構造体データ[]; } * n
8099|  図形は、Zオーダーの奥から順番に格納する。
8100|  flags bit0:ページコピーかどうか
8101|・インクデータ等は CMainFrame::OnEditCopy で格納しています。
8102|************************************************************************/
8103|#if  ERRORS_DEBUG_FALSE
8104|  #define  COPY_TRACE
8105|#endif
8106|
8107|void  CChildView::GetClipData( void* data, bool bPageCopy )
8108|{
8109|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
8110|  ListX_ElemX*  p;
8111|  ListX_ElemX*  p2;
8112|  CadPrim*  prim;
8113|  int*   ip;
8114|  int    size;
8115|  int    n;
8116|
8117|  #ifdef  COPY_TRACE
8118|    Errors_startPool();
8119|  #endif
8120|
8121|  /* クリップボードへ格納するデータを作成する */
8122|  ip = (int*)data + 4;
8123|  size = 4*sizeof(int);
8124|  n = 0;
8125|
8126|
8127|  /* ページタイトルを格納する */
8128|  if ( bPageCopy ) {
8129|    char*  title = SVGCat_File_getCurrentPage( &app->m_file )->title;
8130|    int  title_size = ( strlen( title ) + 4 ) & ~3;
8131|
8132|    strcpy( (char*)ip, title );
8133|    ip = (int*)( (char*)ip + title_size );
8134|    size += title_size;
8135|  }
8136|
8137|
8138|  /* 図形データを格納する */
8139|  for ( ListX_forEach( &app->m_file.m_prims, &p, ListX_ElemX ) ) {
8140|    if ( bPageCopy )  p2 = p;
8141|    else {
8142|      for ( ListX_forEach( &m_MultiSelects, &p2, ListX_ElemX ) ) {
8143|        if ( p->p == p2->p )  break;
8144|      }
8145|    }
8146|    if ( p2 != NULL ) {
8147|      prim = (CadPrim*)p->p;
8148|      #ifdef  COPY_TRACE
8149|        prim->print("Copy");
8150|      #endif
8151|      *(ip + 0) = 2*sizeof(int) + prim->GetSerializedSize();
8152|      *(ip + 1) = prim->GetTypeID();
8153|      prim->CopyToSerial( ip + 2 );
8154|      size += *(ip + 0);
8155|      ip = (int*)( (char*)ip + *(ip + 0) );
8156|      n++;
8157|    }
8158|  }
8159|
8160|
8161|  /* ヘッダを作成する */
8162|  ip = (int*)data;
8163|  *(ip + 0) = size;
8164|  *(ip + 1) = ( bPageCopy ? 1 : 0 );
8165|  *(ip + 2) = n;
8166|  if ( n > 0 ) {
8167|    *(ip + 3) = ( bPageCopy ?
8168|      ((CadPrim*)ListX_getFirst( &app->m_file.m_prims, ListX_ElemX )->p)->GetID() :
8169|      m_HoldPrim->GetID() );
8170|  }
8171|
8172|  #ifdef  COPY_TRACE
8173|    Errors_endPool();
8174|  #endif
8175|}
8176|
8177|
8178| 
8179|/***********************************************************************
8180|  68. <<< [CChildView::Paste] クリップボードの図形を貼り付ける >>> 
8181|【引数】
8182|  ・int  count;         同じデータを貼り付けた回数(1〜)
8183|  ・RECT*  pasteArea;  (出力)貼り付けた図形が入る矩形の位置(NULL可)
8184|【補足】
8185|・フォーマットは、CChildView::GetClipData を参照。
8186|・インクやテキストは、CMainFrame::OnEditPaste で貼り付けます。
8187|************************************************************************/
8188|#if  ERRORS_DEBUG_FALSE
8189|  #define  PASTE_TRACE
8190|#endif
8191|
8192|void  CChildView::Paste( void* data, int count, RECT* pasteArea )
8193|{
8194|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
8195|  CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
8196|  ListX_ElemX*  p;
8197|  CadPrim*  prim;
8198|  StrX_ListElem2*  sp;
8199|  int*   ip;
8200|  int    i;
8201|  int    n;
8202|  int    iBase;
8203|  ListX  ids;  /* ID の変更履歴, StrX_ListElem2::p = oldID, StrX_ListElem2:data=newID */
8204|  bool   bPagePaste = false;
8205|  CadPrim_DrawParam  pa;
8206|
8207|  for ( ListX_forEach( &m_MultiHolds, &p, ListX_ElemX ) )
8208|    ((CadPrim*)p->p)->SetHold( false );
8209|  ListX_toEmptyDelete( &m_MultiHolds, ListX_ElemX, NULL );
8210|  m_HoldPrim = NULL;
8211|
8212|  #ifdef  PASTE_TRACE
8213|    Errors_startPool();
8214|    app->printPrims(&app->m_file.m_prims,"1");
8215|  #endif
8216|
8217|  if ( pasteArea != NULL )
8218|    GetDrawParam( &pa );
8219|
8220|  ListX_init( &ids );
8221|
8222|  ip = (int*)data;
8223|  n = *(ip + 2);
8224|  iBase = *(ip + 3);
8225|
8226|  /* ページコピーしたものは、新しいページを作る */
8227|  if ( *(ip + 1) & 1 ) {
8228|    SVGCat_Page*  newPage;
8229|    CTreeCtrl*  tree = &frame->m_Left->GetTreeCtrl();
8230|
8231|    frame->OnNewPrevPage();
8232|    newPage = SVGCat_File_getCurrentPage( &app->m_file );
8233|    strcpy( newPage->title, (char*)(ip + 4) );
8234|    ip = (int*)( (char*)ip + ( ( strlen( (char*)(ip + 4) ) + 4 ) & ~3 ) );
8235|    tree->SetItemText( tree->GetSelectedItem(), newPage->title );
8236|
8237|    count = 0;
8238|    bPagePaste = true;
8239|  }
8240|  ip += 4;
8241|
8242|
8243|  /* 複製を生成する */
8244|  /* m_MultiHolds に一旦 m_MultiSelects に相当するものを設定する */
8245|  for ( i = 0; i < n; i++ ) {
8246|    switch ( *(ip + 1) ) {
8247|      case  Rect_Ex_TypeID:      prim = new Rect_Ex;  break;
8248|      case  Line_Ex_TypeID:      prim = new Line_Ex;  break;
8249|      case  Line_Corner_TypeID:  prim = new Line_Corner;  break;
8250|      case  Text_Box_TypeID:     prim = new Text_Box;  break;
8251|      case  Matome_TypeID:       prim = new Matome;  break;
8252|      default:  error();
8253|    }
8254|    prim->CopyFromSerial( ip + 2 );
8255|    sp = ListX_addFirstMalloc( &ids, StrX_ListElem2 );
8256|    sp->p = (char*)prim->GetID();  sp->data = NULL;  /* NewID は PasteAdjust で作成する */
8257|
8258|    app->AddPrim( &app->m_file, prim );
8259|    p = ListX_addLastMalloc( &m_MultiHolds, ListX_ElemX );
8260|    p->p = prim;
8261|    prim->SetHold( true );
8262|    if ( i == iBase )  m_HoldPrim = prim;
8263|
8264|    /* pasteArea を更新する */
8265|    if ( pasteArea != NULL ) {
8266|      RECT  rc;
8267|
8268|      prim->Draw( &m_MinBitmapDC, &pa );  /* Text_Box の範囲を決定するため */
8269|      rc.left = prim->GetForAlign( CadPrim_AlignLeft ) + 8 * count;
8270|      rc.right = prim->GetForAlign( CadPrim_AlignRight ) + 8 * count;
8271|      rc.top = prim->GetForAlign( CadPrim_AlignTop ) + 8 * count;
8272|      rc.bottom = prim->GetForAlign( CadPrim_AlignBottom ) + 8 * count;
8273|
8274|      if ( i == 0 ) {
8275|        *pasteArea = rc;
8276|      }
8277|      else {
8278|        if ( rc.left < pasteArea->left )  pasteArea->left = rc.left;
8279|        if ( rc.right > pasteArea->right )  pasteArea->right = rc.right;
8280|        if ( rc.top < pasteArea->top )  pasteArea->top = rc.top;
8281|        if ( rc.bottom > pasteArea->bottom )  pasteArea->bottom = rc.bottom;
8282|      }
8283|    }
8284|
8285|    ip = (int*)( (char*)ip + *(ip + 0) );
8286|  }
8287|
8288|  if ( n > 0 )
8289|    PasteAdjust( &ids, +8 * count, +8 * count );
8290|
8291|  /* アンドゥ・バッファに登録する */
8292|  if ( ! bPagePaste ) {
8293|    ListX_reverse( &m_MultiSelects, ListX_ElemX );  /* 手前から */
8294|    for ( ListX_forEach( &m_MultiSelects, &p, ListX_ElemX ) ) {
8295|      app->m_UndoBuf->AllocNewStep( NULL,
8296|        ((CadPrim*)p->p)->GetNewCopy( &app->m_file.m_prims ), NULL, NULL,
8297|        app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
8298|    }
8299|    ListX_reverse( &m_MultiSelects, ListX_ElemX );
8300|  }
8301|
8302|  ListX_finish2( &ids, StrX_ListElem2, NULL );
8303|}
8304|
8305|
8306|void  CChildView::PasteAdjust( ListX* ids, int dx, int dy )
8307|{
8308|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
8309|  CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
8310|  ListX_ElemX*  p2;
8311|  CadPrim_Link*  link;
8312|  CadPrim_Link** links;
8313|  CadPrim_Link*  links2;
8314|  ListX_ElemX*  p;
8315|  StrX_ListElem2*  sp;
8316|  int    iLink;
8317|  int    i, n, n2;
8318|  CadPrim*  prim;
8319|
8320|  #ifdef  PASTE_TRACE
8321|    app->printPrims(&app->m_file.m_prims,"2");
8322|  #endif
8323|
8324|  /* 新しく生成した図形の ID を変更する */
8325|  i = 0;
8326|  for ( ListX_forEach( ids, &sp, StrX_ListElem2 ) ) {
8327|    if ( (int)sp->p > i )  i = (int)sp->p;
8328|  }
8329|  if ( app->m_NextID < i + 1 )
8330|    app->m_NextID = i + 1;  /* 別の exe から貼り付けたときに重ならないようにする */
8331|  for ( ListX_forEach( ids, &sp, StrX_ListElem2 ) ) {
8332|    sp->data = (void*)app->GetNewPrimID();
8333|  }
8334|  for ( ListX_forEach( ids, &sp, StrX_ListElem2 ) ) {
8335|    for ( ListX_forEach( &m_MultiHolds, &p, ListX_ElemX ) ) {
8336|      #ifdef  PASTE_TRACE
8337|        Errors_printf( "prim[%d]: chg ID  from %d to %d",
8338|          ((CadPrim*)p->p)->GetID(), (int)sp->p, (int)sp->data );
8339|      #endif
8340|      ((CadPrim*)p->p)->OnChgedLinkID( (int)sp->p, (int)sp->data );
8341|      if ( ((CadPrim*)p->p)->GetID() == (int)sp->p )
8342|        ((CadPrim*)p->p)->SetID( (int)sp->data );
8343|    }
8344|  }
8345|
8346|  /* 画像の ImgWorkFilePath と DDB のパスを変更し、その両方をコピーする */
8347|  for ( ListX_forEach( &m_MultiHolds, &p, ListX_ElemX ) ) {
8348|    if ( ((CadPrim*)p->p)->GetTypeID() == Rect_Ex_TypeID ) {
8349|      Rect_Ex*  r = (Rect_Ex*)p->p;
8350|      char  src_path[_MAX_PATH];
8351|
8352|      strcpy( src_path, r->m_ImgWorkPath );
8353|      r->m_ImgWorkPath = app->GetImgWorkFilePath( (long)frame->m_hWnd );
8354|      if ( FileX_isExist( src_path ) )
8355|        FileX_copy( r->m_ImgWorkPath, src_path );
8356|
8357|      if ( r->m_ddb.path[0] != '\0' ) {
8358|        strcpy( r->m_ddb.path, r->m_ImgWorkPath );
8359|        StrX_chgExt( r->m_ddb.path, "ddb" );
8360|      }
8361|    }
8362|  }
8363|
8364|  #ifdef  PASTE_TRACE
8365|    app->printPrims(&app->m_file.m_prims,"3");
8366|  #endif
8367|
8368|  /* リンクを再調整する */
8369|  for ( ListX_forEach( &m_MultiHolds, &p, ListX_ElemX ) )
8370|    ((CadPrim*)p->p)->AdjustLinks( &app->m_file.m_prims );
8371|
8372|
8373|  #ifdef  PASTE_TRACE
8374|    app->printPrims(&app->m_file.m_prims,"3.5");
8375|  #endif
8376|
8377|
8378|  /* リンクした図形(ライン)がペーストした図形に含まれないときは、リンクからはずす */
8379|  for ( ListX_forEach( &m_MultiHolds, &p, ListX_ElemX ) ) {
8380|    prim = (CadPrim*)p->p;
8381|
8382|    /* LinkToHandle について */
8383|    n = prim->GetNumOfLinkToHandle();
8384|    links = new CadPrim_Link*[n];  n2 = 0;
8385|    for ( i = 1; i <= n; i++ ) {
8386|      link = prim->GetLinkToHandle( i );
8387|      if ( link == NULL )  continue;
8388|      for ( ListX_forEach( &m_MultiHolds, &p2, ListX_ElemX ) ) {
8389|        if ( link->prim->GetID() == ((CadPrim*)p2->p)->GetID() )  break;
8390|      }
8391|      if ( p2 == NULL )
8392|        { links[n2] = link;  n2++; }
8393|    }
8394|    for ( i = 0; i < n2; i++ ) {
8395|      prim->UnlinkToHandle( links[i]->prim, links[i]->iHandle, false );
8396|      /* 途中でリンクを削除するとリンク番号がずれるため、ここで削除している */
8397|    }
8398|    delete [] links;
8399|
8400|
8401|    /* LinkToControler について */
8402|    n = prim->GetNumOfLinkToControler();
8403|    links2 = new CadPrim_Link[n];  n2 = 0;
8404|    for ( i = 1; i <= n; i++ ) {
8405|      iLink = prim->GetLinkIDToControler( i );
8406|      if ( iLink == NULL )  continue;
8407|      for ( ListX_forEach( &m_MultiHolds, &p2, ListX_ElemX ) ) {
8408|        if ( iLink == ((CadPrim*)p2->p)->GetID() )  break;
8409|      }
8410|      if ( p2 == NULL ) {
8411|        links2[n2].iHandle = i;
8412|        links2[n2].prim = prim->GetLinkToControler( i );;
8413|        n2++;
8414|      }
8415|    }
8416|    for ( i = 0; i < n2; i++ ) {
8417|      prim->UnlinkToControler( links2[i].iHandle, links2[i].prim );
8418|      /* 途中でリンクを削除するとリンク番号がずれるため、ここで削除している */
8419|    }
8420|    delete [] links2;
8421|  }
8422|
8423|
8424|  #ifdef  PASTE_TRACE
8425|    app->printPrims(&app->m_file.m_prims,"4");
8426|  #endif
8427|
8428|  /* 選択状態にできない図形を MultiHolds から除く */
8429|  for ( p = ListX_getFirst( &m_MultiHolds, ListX_ElemX );  p != NULL; ) {
8430|    prim = (CadPrim*)p->p;
8431|
8432|    if ( ! prim->IsHoldable() ) {
8433|      p2 = ListX_Elem_getNextT( p, ListX_ElemX );
8434|      prim->SetHold( false );
8435|      ListX_removeFree( &m_MultiHolds, p );
8436|      p = p2;
8437|    }
8438|    else
8439|      p = ListX_Elem_getNextT( p, ListX_ElemX );
8440|  }
8441|
8442|  /* HoldPrim を設定する */
8443|  p = ListX_getFirst( &m_MultiHolds, ListX_ElemX );
8444|  m_HoldPrim = ( p == NULL ? NULL : (CadPrim*)p->p );
8445|
8446|  #ifdef  PASTE_TRACE
8447|    app->printPrims(&app->m_file.m_prims,"5");
8448|  #endif
8449|
8450|  /* 貼り付ける図形はずらして貼り付ける */
8451|  SetDrawnParam( &m_MultiHolds );  /* Move 内の Text_Box::GetBox に必要な描画属性を取得する */
8452|  for ( ListX_forEach( &m_MultiHolds, &p, ListX_ElemX ) ) {
8453|    ((CadPrim*)p->p)->Move( dx, dy );
8454|  }
8455|
8456|  SetMultiSelect();
8457|
8458|  #ifdef  PASTE_TRACE
8459|    app->printPrims(&app->m_file.m_prims,"6");
8460|  #endif
8461|
8462|
8463|  /* 再描画する */
8464|  Redraw( false );
8465|  frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
8466|
8467|
8468|  #ifdef  PASTE_TRACE
8469|    Errors_endPool();
8470|  #endif
8471|}
8472|
8473|
8474|void  CChildView::PasteText( void* data, bool bMultiText, RECT* pasteArea )
8475|{
8476|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
8477|  CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
8478|  Text_Box*  text;
8479|  ListX_ElemX*  p;
8480|  int  i;
8481|  CadPrim_DrawParam  pa;
8482|
8483|  if ( pasteArea != NULL )
8484|    GetDrawParam( &pa );
8485|
8486|  if ( bMultiText ) {
8487|    char*  sp;
8488|    char   s[1024];
8489|
8490|    for ( i = 1; ; i++ ) {
8491|      sp = StrX_cpy1Line( s, sizeof(s), (char*)data, i );
8492|      if ( sp == NULL )  break;
8493|
8494|      if ( sp[0] == '\0' ) {
8495|        if ( m_TextCreateY > app->m_file.m_Canvas.m_Height )
8496|          { m_TextCreateY = 30;  m_TextCreateX += 60; }
8497|        if ( m_TextCreateX > app->m_file.m_Canvas.m_Width )
8498|          m_TextCreateX = 30;
8499|        m_TextCreateY += 30;
8500|      }
8501|      else {
8502|        text = NewTextOnEditPaste();
8503|        text->m_Text = sp;
8504|        m_HoldPrim = text;
8505|        p = ListX_addLastMalloc( &m_MultiHolds, ListX_ElemX );
8506|        p->p = m_HoldPrim;
8507|
8508|        /* pasteArea を更新する */
8509|        if ( pasteArea != NULL ) {
8510|          RECT  rc;
8511|
8512|          text->Draw( &m_MinBitmapDC, &pa );  /* Text_Box の範囲を決定するため */
8513|          rc.left = text->GetForAlign( CadPrim_AlignLeft );
8514|          rc.right = text->GetForAlign( CadPrim_AlignRight );
8515|          rc.top = text->GetForAlign( CadPrim_AlignTop );
8516|          rc.bottom = text->GetForAlign( CadPrim_AlignBottom );
8517|
8518|          if ( i == 1 ) {
8519|            *pasteArea = rc;
8520|          }
8521|          else {
8522|            if ( rc.left < pasteArea->left )  pasteArea->left = rc.left;
8523|            if ( rc.right > pasteArea->right )  pasteArea->right = rc.right;
8524|            if ( rc.top < pasteArea->top )  pasteArea->top = rc.top;
8525|            if ( rc.bottom > pasteArea->bottom )  pasteArea->bottom = rc.bottom;
8526|          }
8527|        }
8528|      }
8529|    }
8530|  }
8531|  else {
8532|    text = NewTextOnEditPaste();
8533|    text->m_Text = (char*)data;
8534|    m_HoldPrim = text;
8535|    p = ListX_addLastMalloc( &m_MultiHolds, ListX_ElemX );
8536|    p->p = m_HoldPrim;
8537|
8538|    /* pasteArea を更新する */
8539|    if ( pasteArea != NULL ) {
8540|      text->Draw( &m_MinBitmapDC, &pa );  /* Text_Box の範囲を決定するため */
8541|      pasteArea->left = text->GetForAlign( CadPrim_AlignLeft );
8542|      pasteArea->right = text->GetForAlign( CadPrim_AlignRight );
8543|      pasteArea->top = text->GetForAlign( CadPrim_AlignTop );
8544|      pasteArea->bottom = text->GetForAlign( CadPrim_AlignBottom );
8545|    }
8546|  }
8547|  SetMultiSelect();
8548|
8549|
8550|  /* アンドゥ・バッファに登録する */
8551|  ListX_reverse( &m_MultiSelects, ListX_ElemX );  /* 手前から */
8552|  for ( ListX_forEach( &m_MultiSelects, &p, ListX_ElemX ) ) {
8553|    app->m_UndoBuf->AllocNewStep( NULL,
8554|      ((CadPrim*)p->p)->GetNewCopy( &app->m_file.m_prims ), NULL, NULL,
8555|      app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
8556|  }
8557|  ListX_reverse( &m_MultiSelects, ListX_ElemX );
8558|
8559|  /* 再描画する */
8560|  Redraw( false );
8561|  frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
8562|}
8563|
8564|
8565|
8566|void  CChildView::AnimateOnPaste()
8567|{
8568|  int  d;
8569|  DWORD  tm, tm2;
8570|  int  diff, dd;
8571|  ListX_ElemX*  p;
8572|  enum { interval = 50 };
8573|
8574|  tm = GetTickCount();
8575|  for ( d = -4; d <= 4; d++ ) {
8576|    tm2 = GetTickCount();
8577|    if ( tm2 - tm > interval ) {
8578|      dd = (tm2 - tm) / interval;
8579|      if ( d + dd > 4 )  dd = 4 - d;
8580|      diff = 0;
8581|      while ( dd > 0 ) {
8582|        diff += d;
8583|        d++;  dd--;
8584|      }
8585|      diff += d;
8586|    }
8587|    else
8588|      diff = d;
8589|    if ( tm2 - tm < interval )  Sleep( interval - (tm2 - tm) );
8590|    tm = tm2;
8591|    for ( ListX_forEach( &m_MultiSelects, &p, ListX_ElemX ) ) {
8592|      ((CadPrim*)p->p)->Move( 0, diff );
8593|    }
8594|    Redraw( false );
8595|  }
8596|}
8597|
8598|
8599| 
8600|/***********************************************************************
8601|  69. <<< [CChildView::OnSetPageButton] ページ切り替えボタンを背景に貼り付ける >>> 
8602|************************************************************************/
8603|void CChildView::OnSetPageButton()
8604|{
8605|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
8606|  CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
8607|  Text_Box*  text;
8608|  Text_Box*  text2;
8609|  int  page = app->m_file.m_CurrentPageNum;
8610|
8611|  if ( page != 0 )  frame->OnMakeBackPage();
8612|
8613|  text = new Text_Box;
8614|  text->m_id = app->GetNewPrimID();
8615|  text->m_bHold = false;
8616|  text->m_Text = "<Back";
8617|  text->m_URL = "script:nextPage( evt, -1 )";
8618|  text->m_CenterX = 5;  text->m_Y = 15;
8619|  text->m_W = 32;  text->m_10H = 320;
8620|  text->m_Color = RGB(0,0x80,0);
8621|  text->m_Font = _DefaultFont;
8622|  text->m_Size = 10;
8623|  text->m_bBold = true;
8624|  text->m_bItalic = false;
8625|  text->m_BasePos = Text_Box_LeftAlign;
8626|  text->m_BoxShape = Text_Box_NoFrame;
8627|  text->m_BoxMarginX = 2;  text->m_BoxMarginY = 2;
8628|  text->m_BorderWidth = 0;
8629|  text->m_BorderColor = 0x000000;
8630|  text->m_FillColor = 0xFFFFFF;
8631|
8632|  text2 = new Text_Box;
8633|  text2->copy( text, &app->m_file.m_prims );
8634|  text2->m_Text = "Next>";
8635|  text2->m_URL = "script:nextPage( evt, +1 )";
8636|  text2->m_CenterX = 60;
8637|
8638|  app->AddPrim( &app->m_file, text );
8639|  app->AddPrim( &app->m_file, text2 );
8640|
8641|
8642|  /* アンドゥバッファに記録する */
8643|  app->m_UndoBuf->StartMulti();
8644|  app->m_UndoBuf->AllocNewStep( NULL,
8645|    text2->GetNewCopy( &app->m_file.m_prims ), NULL, NULL,
8646|    app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
8647|  app->m_UndoBuf->AllocNewStep( NULL,
8648|    text->GetNewCopy( &app->m_file.m_prims ), NULL, NULL,
8649|    app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
8650|  app->m_UndoBuf->EndMulti();
8651|
8652|
8653|  if ( page != 0 )  frame->OnMakeBackPage();
8654|  else  Redraw( false );
8655|
8656|  MessageBox(
8657|    app->m_bJapanese ?
8658|    "背景の左上にページ切り替えボタン '<Back' と 'Next>' を作成しました。\r\n"
8659|    "このボタンは、SVG ビューアで表示したときにクリックできます。\r\n"
8660|    "SVG Cats では、適当な位置に移動したり、プロパティを変更することができます。" :
8661|    "Page changing buttons '<Back' and 'Next>' was made on left up of background. "
8662|    "This button can be clicked on SVG Viewer.\r\n"
8663|    "In SVG Cats, You can move it and change property.", MB_OK );
8664|}
8665|
8666| 
8667|/***********************************************************************
8668|  70. <<< [CChildView::NewTextOnEditPaste] >>> 
8669|************************************************************************/
8670|Text_Box*  CChildView::NewTextOnEditPaste()
8671|{
8672|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
8673|  CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
8674|  Text_Box*  text;
8675|
8676|  if ( m_TextCreateY > app->m_file.m_Canvas.m_Height )
8677|    { m_TextCreateY = 30;  m_TextCreateX += 60; }
8678|
8679|  if ( m_TextCreateX > app->m_file.m_Canvas.m_Width )
8680|    m_TextCreateX = 30;
8681|
8682|  if ( frame->m_TextRectDesign != NULL ) {
8683|    text = (Text_Box*)frame->m_TextRectDesign->GetNewCopy( &app->m_file.m_prims );
8684|    text->m_id = app->GetNewPrimID();
8685|    text->m_CenterX = m_TextCreateX;
8686|    text->m_Y = m_TextCreateY;
8687|  }
8688|  else {
8689|    text = new Text_Box;
8690|    text->m_id = app->GetNewPrimID();
8691|    text->m_Text = "ABC";
8692|    text->m_CenterX = m_TextCreateX;
8693|    text->m_Y = m_TextCreateY;
8694|    text->m_W = 100;  text->m_10H = 320;
8695|    text->m_Color = 0;
8696|    text->m_Font = _DefaultFont;
8697|    text->m_Size = 10;
8698|    text->m_bBold = false;  text->m_bItalic = false;
8699|    text->m_BasePos = Text_Box_LeftAlign;
8700|    text->m_BoxShape = Text_Box_RectShape;
8701|    text->m_BoxMarginX = 8;  text->m_BoxMarginY = 6;
8702|    text->m_BorderWidth = 1;
8703|    text->m_BorderColor = 0x000000;
8704|    text->m_FillColor = 0xFFFFFF;
8705|  }
8706|  text->SetHold( true );
8707|  app->AddPrim( &app->m_file, text );
8708|
8709|  m_TextCreateY += 30;
8710|
8711|  return  text;
8712|}
8713|
8714|
8715| 
8716|/***********************************************************************
8717|  71. <<< [CChildView::OnDel] >>> 
8718|************************************************************************/
8719|void CChildView::OnDel()
8720|{
8721|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
8722|  CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
8723|
8724|  if ( frame->m_wndSplitter.GetActivePane() == frame->m_Left ) {
8725|    frame->OnDelPage();
8726|  }
8727|
8728|  /* メインビューに対する削除 */
8729|  else {
8730|    HRESULT  hr;
8731|    IInkStrokes*  selection;
8732|    IInkDisp*  ink;
8733|    long  n;
8734|
8735|    app->m_UndoBuf->StartMulti();
8736|
8737|
8738|    /* インクを削除する */
8739|    if ( m_InkOverlay != NULL ) {
8740|      hr = m_InkOverlay->get_Ink( &ink );
8741|      if ( hr != 0 )  error();
8742|
8743|      hr = m_InkOverlay->get_Selection( &selection );
8744|      if ( hr != 0 )  error();
8745|
8746|      hr = selection->get_Count( &n );
8747|      if ( hr != 0 )  error();
8748|
8749|      if ( n > 0 ) {
8750|
8751|        /*(memo) ExtractStrokes した後で GetBoundingBox すると、*/
8752|        /* (0,0,0,0) になってしまうのは、IEF_Default == IEF_RemoveFromOriginal だから。*/
8753|        /* しかし、ExtractStrokes した Ink から ExtractStrokes するとエラーになる(?) */
8754|        #if 0
8755|        hr = selection->GetBoundingBox( IBBM_Default, &m_UndoInk_Rect );
8756|        if ( hr != 0 )  error();
8757|
8758|        hr = ink->ExtractStrokes( selection, IEF_Default, &m_UndoInk );
8759|        if ( hr != 0 )  error();
8760|        #endif
8761|
8762|        /* アンドゥ領域に記録する */
8763|        app->m_UndoBuf->AllocNewStep_Ink2( Undo_Ink_Del, ink, selection,
8764|          false, app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
8765|
8766|        /* インクを削除する */
8767|        hr = ink->DeleteStrokes( selection );
8768|        if ( hr != 0 )  error();
8769|
8770|        SelectInkToEmpty();
8771|
8772|        Redraw( false );
8773|      }
8774|
8775|      selection->Release();  selection = NULL;
8776|      ink->Release();  ink = NULL;
8777|    }
8778|
8779|
8780|    /* 図形を削除する */
8781|    if ( m_HoldPrim != NULL ) {
8782|      CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
8783|
8784|      OnFinishPrimMove();
8785|
8786|      if ( ListX_getN( &m_MultiHolds, ListX_ElemX ) == 0 ) {
8787|        OnDel_setUndoBuf( m_HoldPrim );
8788|        OnDel_sub( m_HoldPrim );
8789|      }
8790|      else {
8791|        ListX_ElemX*  p;
8792|
8793|        ListX_reverse( &m_MultiSelects, ListX_ElemX );  /* 手前から登録する */
8794|        for ( ListX_forEach( &m_MultiSelects, &p, ListX_ElemX ) ) {
8795|          OnDel_setUndoBuf( (CadPrim*)p->p );
8796|        }
8797|        ListX_reverse( &m_MultiSelects, ListX_ElemX );
8798|
8799|        for ( ListX_forEach( &m_MultiSelects, &p, ListX_ElemX ) ) {
8800|          OnDel_sub( (CadPrim*)p->p );
8801|        }
8802|      }
8803|
8804|      ListX_toEmptyDelete( &m_MultiHolds, ListX_ElemX, NULL );
8805|      m_HoldPrim = NULL;
8806|      Redraw( false );
8807|      frame->ResetProp();
8808|    }
8809|
8810|    app->m_UndoBuf->EndMulti();
8811|  }
8812|}
8813|
8814|
8815|void  CChildView::OnDel_setUndoBuf( CadPrim* prim )
8816|{
8817|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
8818|  ListX_ElemX*  p;
8819|  ListX_ElemX*  p2;
8820|  CadPrim*  nextPrim;
8821|
8822|  /* 1つ手前の要素を nextPrim に格納する。ただし、いっしょに削除するものは除く */
8823|  for ( ListX_forEach( &app->m_file.m_prims, &p, ListX_ElemX ) ) {
8824|    if ( (CadPrim*)p->p == prim )
8825|      break;
8826|  }
8827|  ASSERT( p != NULL );
8828|  do {
8829|    p = ListX_Elem_getNextT( p, ListX_ElemX );
8830|    if ( p == NULL )  nextPrim = NULL;
8831|    else  nextPrim = (CadPrim*)p->p;
8832|
8833|    for ( ListX_forEach( &m_MultiSelects, &p2, ListX_ElemX ) ) {
8834|      if ( p2->p == nextPrim )  break;
8835|    }
8836|    if ( p2 == NULL )  break;
8837|  } while ( p != NULL );
8838|
8839|  app->m_UndoBuf->AllocNewStep( prim->GetNewCopy( &app->m_file.m_prims ),
8840|    NULL, nextPrim == NULL ?  NULL : nextPrim->GetNewCopy( &app->m_file.m_prims),
8841|    NULL, app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
8842|}
8843|
8844|
8845|void  CChildView::OnDel_sub( CadPrim* prim )
8846|{
8847|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
8848|
8849|  prim->UnlinkAll();
8850|  app->RemovePrim( &app->m_file, prim );
8851|}
8852|
8853|
8854| 
8855|/***********************************************************************
8856|  72. <<< [CChildView::OnSpcKey] >>> 
8857|************************************************************************/
8858|void CChildView::OnSpcKey()
8859|{
8860|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
8861|  CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
8862|  Text_Box*  text;
8863|  ListX_ElemX*  p;
8864|
8865|  OnFinishPrimMove();
8866|
8867|  /* 選択状態を無くす */
8868|  m_HoldPrim = NULL;
8869|  for ( ListX_forEach( &app->m_file.m_prims, &p, ListX_ElemX ) )
8870|    ((CadPrim*)p->p)->SetHold( false );
8871|  ListX_toEmptyDelete( &m_MultiHolds, ListX_ElemX, NULL );
8872|  SetMultiSelect();
8873|
8874|
8875|  /* 新規にテキストを作成する */
8876|  if ( m_TextCreateY > app->m_file.m_Canvas.m_Height )
8877|    { m_TextCreateY = 30;  m_TextCreateX += 60; }
8878|
8879|  if ( m_TextCreateX > app->m_file.m_Canvas.m_Width )
8880|    m_TextCreateX = 30;
8881|
8882|  if ( frame->m_TextRectDesign != NULL ) {
8883|    text = (Text_Box*)frame->m_TextRectDesign->GetNewCopy( &app->m_file.m_prims );
8884|    text->m_id = app->GetNewPrimID();
8885|    text->m_CenterX = m_TextCreateX;
8886|    text->m_Y = m_TextCreateY;
8887|  }
8888|  else {
8889|    text = new Text_Box;
8890|    text->m_id = app->GetNewPrimID();
8891|    text->m_Text = "ABC";
8892|    text->m_CenterX = m_TextCreateX;
8893|    text->m_Y = m_TextCreateY;
8894|    text->m_W = 100;  text->m_10H = 320;
8895|    text->m_Color = 0;
8896|    text->m_Font = _DefaultFont;
8897|    text->m_Size = 10;
8898|    text->m_bBold = false;  text->m_bItalic = false;
8899|    text->m_BasePos = Text_Box_LeftAlign;
8900|    text->m_BoxShape = Text_Box_RectShape;
8901|    text->m_BoxMarginX = 8;  text->m_BoxMarginY = 6;
8902|    text->m_BorderWidth = 1;
8903|    text->m_BorderColor = 0x000000;
8904|    text->m_FillColor = 0xFFFFFF;
8905|  }
8906|
8907|  text->SetHold( true );
8908|  app->AddPrim( &app->m_file, text );
8909|  m_HoldPrim = text;
8910|  p = ListX_addFirstMalloc( &m_MultiHolds, ListX_ElemX );
8911|  p->p = text;
8912|  SetMultiSelect();
8913|  Redraw( false );
8914|  m_TextCreateY += 30;
8915|
8916|  Redraw( false );
8917|
8918|
8919|  /* テキストの内容をユーザから入力する */
8920| if ( 0 && m_InkOverlay != NULL ) {
8921|  CInputML  dlg;
8922|
8923|  dlg.m_ID = (void*)text->GetID();
8924|  dlg.m_Text = text->m_Text;
8925|  dlg.m_PenInputPanel = m_PenInputPanel;
8926|  dlg.m_bDispPenPanel = m_bInputML_bDispPenPanel;
8927|  dlg.m_SaveObj = this;  dlg.m_SaveFunc = (CInputML_SaveF)CChildView_saveOnEditing;
8928|  dlg.m_bCtrlRet = app->m_bCtrlRet;
8929|  dlg.m_bJapanese = app->m_bJapanese;
8930|  dlg.m_bHideMain = app->m_bHideMain;
8931|  dlg.m_HideTarget = frame;
8932|  dlg.m_ShowWindowFunc = (CInputML_ShowWindowF)CMainFrame_ShowWindowFunc;
8933|  dlg.m_kword = frame->m_KWord;
8934|  m_InputML = &dlg;
8935|  m_bInDragPlay = TRUE;  /* ハンドルも表示する */
8936|
8937|  if ( dlg.DoModal() == IDOK ) {
8938|    m_InputML = NULL;
8939|    text->m_Text = dlg.m_Text;
8940|    app->m_UndoBuf->AllocNewStep( NULL,
8941|      text->GetNewCopy( &app->m_file.m_prims ), NULL, NULL, app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
8942|
8943|    Redraw( false );
8944|    frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
8945|  }
8946|  else {
8947|    m_InputML = NULL;
8948|    ResetSelect();
8949|    app->RemovePrim( &app->m_file, text );
8950|    m_TextCreateY -= 30;
8951|    Redraw( false );
8952|    frame->ResetProp();
8953|  }
8954|  m_bInputML_bDispPenPanel = dlg.m_bDispPenPanel;
8955|  app->m_bCtrlRet = dlg.m_bCtrlRet;
8956|  app->m_bHideMain = dlg.m_bHideMain;
8957|  frame->m_KWord = dlg.m_kword;
8958| }
8959| else {
8960|  CInputML1  dlg;
8961|
8962|  dlg.m_ID = (void*)text->GetID();
8963|  dlg.m_Text = text->m_Text;
8964|  dlg.m_PenInputPanel = m_PenInputPanel;
8965|  dlg.m_bDispPenPanel = m_bInputML_bDispPenPanel;
8966|  dlg.m_SaveObj = this;  dlg.m_SaveFunc = (CInputML1_SaveF)CChildView_saveOnEditing1;
8967|  dlg.m_bCtrlRet = app->m_bCtrlRet;
8968|  dlg.m_bJapanese = app->m_bJapanese;
8969|  dlg.m_bHideMain = app->m_bHideMain;
8970|  dlg.m_HideTarget = frame;
8971|  dlg.m_ShowWindowFunc = (CInputML1_ShowWindowF)CMainFrame_ShowWindowFunc;
8972|  dlg.m_kword = frame->m_KWord;
8973|  m_InputML1 = &dlg;
8974|  m_bInDragPlay = TRUE;  /* ハンドルも表示する */
8975|
8976|  if ( dlg.DoModal() == IDOK ) {
8977|    m_InputML1 = NULL;
8978|    text->m_Text = dlg.m_Text;
8979|    app->m_UndoBuf->AllocNewStep( NULL,
8980|      text->GetNewCopy( &app->m_file.m_prims ), NULL, NULL, app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
8981|
8982|    Redraw( false );
8983|    frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
8984|  }
8985|  else {
8986|    m_InputML1 = NULL;
8987|    app->RemovePrim( &app->m_file, text );
8988|    m_HoldPrim = NULL;
8989|    m_TextCreateY -= 30;
8990|    Redraw( false );
8991|    frame->ResetProp();
8992|  }
8993|  m_bInputML_bDispPenPanel = dlg.m_bDispPenPanel;
8994|  app->m_bCtrlRet = dlg.m_bCtrlRet;
8995|  app->m_bHideMain = dlg.m_bHideMain;
8996|  frame->m_KWord = dlg.m_kword;
8997| }
8998|}
8999|
9000|
9001|void CChildView::OnRetKey()
9002|{
9003|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
9004|  CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
9005|
9006|  if ( m_HoldPrim == NULL ) {
9007|    return;
9008|  }
9009|
9010|  switch ( m_HoldPrim->GetTypeID() ) {
9011|
9012|   case  Text_Box_TypeID: {
9013|
9014|   if ( 0 && m_InkOverlay != NULL ) {
9015|    CInputML  dlg;
9016|    Text_Box*  prim = (Text_Box*)m_HoldPrim;
9017|
9018|    dlg.m_ID = (void*)m_HoldPrim->GetID();
9019|    dlg.m_Text = prim->m_Text;
9020|    dlg.m_PenInputPanel = m_PenInputPanel;
9021|    dlg.m_bDispPenPanel = m_bInputML_bDispPenPanel;
9022|    dlg.m_SaveObj = this;  dlg.m_SaveFunc = (CInputML_SaveF)CChildView_saveOnEditing;
9023|    dlg.m_bCtrlRet = app->m_bCtrlRet;
9024|    dlg.m_bJapanese = app->m_bJapanese;
9025|    dlg.m_bHideMain = app->m_bHideMain;
9026|    dlg.m_HideTarget = frame;
9027|    dlg.m_ShowWindowFunc = (CInputML_ShowWindowF)CMainFrame_ShowWindowFunc;
9028|    dlg.m_kword = frame->m_KWord;
9029|    m_InputML = &dlg;
9030|    dlg.DoModal();
9031|      m_InputML = NULL;
9032|      m_BeforePrim = prim->GetNewCopy( &app->m_file.m_prims );
9033|      m_BeforePrim->SetBInUndoBuf( true );
9034|      prim->m_Text = dlg.m_Text;
9035|      app->m_UndoBuf->AllocNewStep( m_BeforePrim,
9036|        m_HoldPrim->GetNewCopy( &app->m_file.m_prims ), NULL, NULL, app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
9037|      m_BeforePrim = NULL;
9038|      Redraw( false );
9039|      frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
9040|    m_bInputML_bDispPenPanel = dlg.m_bDispPenPanel;
9041|    m_InputML = NULL;
9042|    app->m_bCtrlRet = dlg.m_bCtrlRet;
9043|    app->m_bHideMain = dlg.m_bHideMain;
9044|    frame->m_KWord = dlg.m_kword;
9045|   }
9046|   else {
9047|    CInputML1  dlg;
9048|    Text_Box*  prim = (Text_Box*)m_HoldPrim;
9049|
9050|    dlg.m_ID = (void*)m_HoldPrim->GetID();
9051|    dlg.m_Text = prim->m_Text;
9052|    dlg.m_PenInputPanel = m_PenInputPanel;
9053|    dlg.m_bDispPenPanel = m_bInputML_bDispPenPanel;
9054|    dlg.m_SaveObj = this;  dlg.m_SaveFunc = (CInputML1_SaveF)CChildView_saveOnEditing1;
9055|    dlg.m_bCtrlRet = app->m_bCtrlRet;
9056|    dlg.m_bJapanese = app->m_bJapanese;
9057|    dlg.m_bHideMain = app->m_bHideMain;
9058|    dlg.m_HideTarget = frame;
9059|    dlg.m_ShowWindowFunc = (CInputML1_ShowWindowF)CMainFrame_ShowWindowFunc;
9060|    dlg.m_kword = frame->m_KWord;
9061|    m_InputML1 = &dlg;
9062|    dlg.DoModal();
9063|      m_InputML1 = NULL;
9064|      m_BeforePrim = prim->GetNewCopy( &app->m_file.m_prims );
9065|      m_BeforePrim->SetBInUndoBuf( true );
9066|      prim->m_Text = dlg.m_Text;
9067|      app->m_UndoBuf->AllocNewStep( m_BeforePrim,
9068|        m_HoldPrim->GetNewCopy( &app->m_file.m_prims ), NULL, NULL, app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
9069|      m_BeforePrim = NULL;
9070|      Redraw( false );
9071|      frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
9072|    m_bInputML_bDispPenPanel = dlg.m_bDispPenPanel;
9073|    m_InputML1 = NULL;
9074|    app->m_bCtrlRet = dlg.m_bCtrlRet;
9075|    app->m_bHideMain = dlg.m_bHideMain;
9076|    frame->m_KWord = dlg.m_kword;
9077|   }
9078|   }
9079|  }
9080|}
9081|
9082|
9083| 
9084|/***********************************************************************
9085|  73. <<< 前後関係の調整を行う >>> 
9086|************************************************************************/
9087|void CChildView::OnZUp()
9088|{
9089|  if ( m_HoldPrim != NULL ) {
9090|    CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
9091|    CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
9092|    ListX_ElemX*  hold;
9093|    ListX_ElemX*  pos;
9094|    CadPrim*  before_f = NULL;
9095|    CadPrim*  after_f = NULL;
9096|
9097|    m_BeforePrim = m_HoldPrim->GetNewCopy( &app->m_file.m_prims );
9098|
9099|    for ( ListX_forEach( &app->m_file.m_prims, &hold, ListX_ElemX ) ) {
9100|      if ( hold->p == m_HoldPrim )  break;
9101|    }
9102|    pos = ListX_Elem_getNextT( hold, ListX_ElemX );
9103|    if ( pos != NULL ) {
9104|      before_f = ((CadPrim*)pos->p)->GetNewCopy( &app->m_file.m_prims );
9105|      pos = ListX_Elem_getNextT( pos, ListX_ElemX );
9106|
9107|      ListX_remove( &app->m_file.m_prims, hold );
9108|      if ( pos == NULL ) {
9109|        ListX_addLast( &app->m_file.m_prims, hold );
9110|      }
9111|      else {
9112|        ListX_insert( &app->m_file.m_prims, pos, hold );
9113|        after_f = ((CadPrim*)pos->p)->GetNewCopy( &app->m_file.m_prims );
9114|      }
9115|    }
9116|
9117|    app->m_UndoBuf->AllocNewStep( m_BeforePrim,
9118|       m_HoldPrim->GetNewCopy( &app->m_file.m_prims ), before_f, after_f,
9119|       app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
9120|    m_BeforePrim = NULL;
9121|
9122|    Redraw( false );
9123|    frame->OnSelect();
9124|  }
9125|}
9126|
9127|void CChildView::OnZDown()
9128|{
9129|  if ( m_HoldPrim != NULL ) {
9130|    CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
9131|    CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
9132|    ListX_ElemX*  hold;
9133|    ListX_ElemX*  pos;
9134|    CadPrim*  before_f = NULL;
9135|    CadPrim*  after_f = NULL;
9136|
9137|    m_BeforePrim = m_HoldPrim->GetNewCopy( &app->m_file.m_prims );
9138|
9139|    for ( ListX_forEach( &app->m_file.m_prims, &hold, ListX_ElemX ) ) {
9140|      if ( hold->p == m_HoldPrim )  break;
9141|    }
9142|    pos = ListX_Elem_getNextT( hold, ListX_ElemX );
9143|    if ( pos != NULL )
9144|      before_f = ((CadPrim*)pos->p)->GetNewCopy( &app->m_file.m_prims );
9145|
9146|    pos = ListX_getPrev( &app->m_file.m_prims, hold, ListX_ElemX );
9147|    if ( pos != NULL ) {
9148|      ListX_remove( &app->m_file.m_prims, hold );
9149|      ListX_insert( &app->m_file.m_prims, pos, hold );
9150|      after_f = ((CadPrim*)pos->p)->GetNewCopy( &app->m_file.m_prims );
9151|    }
9152|    else
9153|      after_f = before_f->GetNewCopy( &app->m_file.m_prims );
9154|
9155|    app->m_UndoBuf->AllocNewStep( m_BeforePrim,
9156|      m_HoldPrim->GetNewCopy( &app->m_file.m_prims ), before_f, after_f,
9157|      app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
9158|    m_BeforePrim = NULL;
9159|
9160|    Redraw( false );
9161|    frame->OnSelect();
9162|  }
9163|}
9164|
9165|void CChildView::OnZTop()
9166|{
9167|  if ( m_HoldPrim != NULL ) {
9168|    CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
9169|    CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
9170|    ListX_ElemX*  bottomLine = app->GetBottomLine( &app->m_file );
9171|    int  iBottomLine = ListX_getI( &app->m_file.m_prims, bottomLine );
9172|    int  iHold;
9173|    ListX_ElemX*  hold;
9174|    ListX  holds;
9175|    CadPrim*  before_f;
9176|
9177|    ListX_init( &holds );
9178|    hold = ListX_addFirstMalloc( &holds, ListX_ElemX );
9179|    hold->p = m_HoldPrim;
9180|
9181|    m_BeforePrim = m_HoldPrim->GetNewCopy( &app->m_file.m_prims );
9182|    before_f = app->GetNextForUndoBuf( m_HoldPrim, &holds );
9183|
9184|    for ( ListX_forEach( &app->m_file.m_prims, &hold, ListX_ElemX ) ) {
9185|      if ( hold->p == m_HoldPrim )  break;
9186|    }
9187|    iHold = ListX_getI( &app->m_file.m_prims, hold );
9188|
9189|    if ( bottomLine != NULL )
9190|      iBottomLine = ListX_getI( &app->m_file.m_prims, bottomLine );
9191|
9192|    ListX_remove( &app->m_file.m_prims, hold );
9193|    if ( hold != bottomLine &&  bottomLine != NULL && iHold < iBottomLine - 1 )
9194|      ListX_insert( &app->m_file.m_prims, bottomLine, hold );
9195|    else
9196|      ListX_addLast( &app->m_file.m_prims, hold );
9197|
9198|
9199|    app->m_UndoBuf->AllocNewStep( m_BeforePrim, m_HoldPrim->GetNewCopy( &app->m_file.m_prims ),
9200|      before_f, app->GetNextForUndoBuf( m_HoldPrim, &holds ), app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
9201|    m_BeforePrim = NULL;
9202|
9203|
9204|    Redraw( false );
9205|  }
9206|}
9207|
9208|void CChildView::OnZBottom()
9209|{
9210|  if ( m_HoldPrim != NULL ) {
9211|    CSVGCatApp*   app = (CSVGCatApp*)AfxGetApp();
9212|    ListX_ElemX*  hold;
9213|
9214|    ListX  holds;
9215|    CadPrim*  before_f;
9216|
9217|    ListX_init( &holds );
9218|    hold = ListX_addFirstMalloc( &holds, ListX_ElemX );
9219|    hold->p = m_HoldPrim;
9220|
9221|    m_BeforePrim = m_HoldPrim->GetNewCopy( &app->m_file.m_prims );
9222|    before_f = app->GetNextForUndoBuf( m_HoldPrim, &holds );
9223|
9224|    ZBottom( m_HoldPrim );
9225|
9226|    app->m_UndoBuf->AllocNewStep( m_BeforePrim, m_HoldPrim->GetNewCopy( &app->m_file.m_prims ),
9227|      before_f, app->GetNextForUndoBuf( m_HoldPrim, &holds ),
9228|      app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
9229|    m_BeforePrim = NULL;
9230|
9231|    Redraw( false );
9232|  }
9233|}
9234|
9235|void CChildView::ZBottom( CadPrim* target )
9236|{
9237|  CSVGCatApp*   app = (CSVGCatApp*)AfxGetApp();
9238|  ListX_ElemX*  bottomLine = app->GetBottomLine( &app->m_file );
9239|  int  iBottomLine;
9240|  int  iHold;
9241|  ListX_ElemX*  hold;
9242|
9243|  for ( ListX_forEach( &app->m_file.m_prims, &hold, ListX_ElemX ) ) {
9244|    if ( hold->p == target )  break;
9245|  }
9246|  iHold = ListX_getI( &app->m_file.m_prims, hold );
9247|
9248|  if ( bottomLine != NULL )
9249|    iBottomLine = ListX_getI( &app->m_file.m_prims, bottomLine );
9250|
9251|  ListX_remove( &app->m_file.m_prims, hold );
9252|  if ( hold == bottomLine || bottomLine == NULL || iHold < iBottomLine )
9253|    ListX_addFirst( &app->m_file.m_prims, hold );
9254|  else
9255|    ListX_insert( &app->m_file.m_prims, bottomLine, hold );
9256|}
9257|
9258| 
9259|/***********************************************************************
9260|  74. <<< 位置の微調整を行う >>> 
9261|************************************************************************/
9262|void CChildView::OnPrimDown()
9263|{
9264|  if ( m_HoldPrim != NULL ) {
9265|    CSVGCatApp*   app = (CSVGCatApp*)AfxGetApp();
9266|    CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
9267|
9268|    if ( m_BeforePrim == NULL )  SetBeforePrim();
9269|
9270|    if ( ListX_getFirst( &m_MultiSelects, ListX_ElemX ) == NULL )
9271|      m_HoldPrim->Move( 0, +1 );
9272|    else {
9273|      ListX_ElemX*  p;
9274|      for ( ListX_forEach( &m_MultiSelects, &p, ListX_ElemX ) )
9275|        ((CadPrim*)p->p)->Move( 0, +1 );
9276|
9277|      Redraw( false );  /* Text_Box は描画しないと更新されないものがあるため */
9278|
9279|      /* リンクラインのずれを直す */
9280|      for ( ListX_forEach( &m_MultiSelects, &p, ListX_ElemX ) )
9281|        ((CadPrim*)p->p)->Move( 0, 0 );
9282|    }
9283|    Redraw( false );
9284|    frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
9285|  }
9286|}
9287|
9288|void CChildView::OnPrimLeft()
9289|{
9290|  if ( m_HoldPrim != NULL ) {
9291|    CSVGCatApp*   app = (CSVGCatApp*)AfxGetApp();
9292|    CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
9293|
9294|    if ( m_BeforePrim == NULL )  SetBeforePrim();
9295|
9296|    if ( ListX_getFirst( &m_MultiSelects, ListX_ElemX ) == NULL )
9297|      m_HoldPrim->Move( -1, 0 );
9298|    else {
9299|      ListX_ElemX*  p;
9300|      for ( ListX_forEach( &m_MultiSelects, &p, ListX_ElemX ) )
9301|        ((CadPrim*)p->p)->Move( -1, 0 );
9302|
9303|      Redraw( false );  /* Text_Box は描画しないと更新されないものがあるため */
9304|
9305|      /* リンクラインのずれを直す */
9306|      for ( ListX_forEach( &m_MultiSelects, &p, ListX_ElemX ) )
9307|        ((CadPrim*)p->p)->Move( 0, 0 );
9308|    }
9309|    Redraw( false );
9310|    frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
9311|  }
9312|}
9313|
9314|void CChildView::OnPrimRight()
9315|{
9316|  if ( m_HoldPrim != NULL ) {
9317|    CSVGCatApp*   app = (CSVGCatApp*)AfxGetApp();
9318|    CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
9319|
9320|    if ( m_BeforePrim == NULL )  SetBeforePrim();
9321|
9322|    if ( ListX_getFirst( &m_MultiSelects, ListX_ElemX ) == NULL )
9323|      m_HoldPrim->Move( +1, 0);
9324|    else {
9325|      ListX_ElemX*  p;
9326|      for ( ListX_forEach( &m_MultiSelects, &p, ListX_ElemX ) )
9327|        ((CadPrim*)p->p)->Move( +1, 0 );
9328|
9329|      Redraw( false );  /* Text_Box は描画しないと更新されないものがあるため */
9330|
9331|      /* リンクラインのずれを直す */
9332|      for ( ListX_forEach( &m_MultiSelects, &p, ListX_ElemX ) )
9333|        ((CadPrim*)p->p)->Move( 0, 0 );
9334|    }
9335|    Redraw( false );
9336|    frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
9337|  }
9338|}
9339|
9340|void CChildView::OnPrimUp()
9341|{
9342|  if ( m_HoldPrim != NULL ) {
9343|    CSVGCatApp*   app = (CSVGCatApp*)AfxGetApp();
9344|    CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
9345|
9346|    if ( m_BeforePrim == NULL )  SetBeforePrim();
9347|
9348|    if ( ListX_getFirst( &m_MultiSelects, ListX_ElemX ) == NULL )
9349|      m_HoldPrim->Move( 0, -1 );
9350|    else {
9351|      ListX_ElemX*  p;
9352|      for ( ListX_forEach( &m_MultiSelects, &p, ListX_ElemX ) )
9353|        ((CadPrim*)p->p)->Move( 0, -1 );
9354|
9355|      Redraw( false );  /* Text_Box は描画しないと更新されないものがあるため */
9356|
9357|      /* リンクラインのずれを直す */
9358|      for ( ListX_forEach( &m_MultiSelects, &p, ListX_ElemX ) )
9359|        ((CadPrim*)p->p)->Move( 0, 0 );
9360|    }
9361|    Redraw( false );
9362|    frame->SetPropMulti( &m_MultiHolds, m_HoldStrokes );
9363|  }
9364|}
9365|
9366|void  CChildView::SetBeforePrim()
9367|{
9368|  CSVGCatApp*   app = (CSVGCatApp*)AfxGetApp();
9369|  ListX_ElemX*  p;
9370|  ListX_ElemX*  p2;
9371|
9372|  ASSERT( m_BeforePrim == NULL );
9373|  ASSERT( ListX_getN( &m_MultiBefore, ListX_ElemX ) == 0 );
9374|
9375|  app->m_UndoBuf->ClearAfterSteps();
9376|
9377|  m_BeforePrim = m_HoldPrim->GetNewCopy( &app->m_file.m_prims );
9378|  m_BeforePrim->SetBInUndoBuf( true );
9379|
9380|  for ( ListX_forEach( &m_MultiSelects, &p, ListX_ElemX ) ) {
9381|    p2 = ListX_addLastMalloc( &m_MultiBefore, ListX_ElemX );
9382|    p2->p = (void*)((CadPrim*)p->p)->GetNewCopy( &app->m_file.m_prims );
9383|    ((CadPrim*)p2->p)->SetBInUndoBuf( true );
9384|  }
9385|}
9386|
9387|void  CChildView::OnFinishPrimMove()
9388|{
9389|  CSVGCatApp*   app = (CSVGCatApp*)AfxGetApp();
9390|
9391|  if ( m_BeforePrim != NULL ) {
9392|    if ( ListX_getN( &m_MultiSelects, ListX_ElemX ) == 0 ) {
9393|      app->m_UndoBuf->AllocNewStep( m_BeforePrim,
9394|        m_HoldPrim->GetNewCopy( &app->m_file.m_prims ), NULL, NULL, app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
9395|    }
9396|    else {
9397|      ListX_ElemX*  p;
9398|      ListX_ElemX*  p2;
9399|
9400|      app->m_UndoBuf->StartMulti();
9401|      p2 = ListX_getFirst( &m_MultiBefore, ListX_ElemX );
9402|      for ( ListX_forEach( &m_MultiSelects, &p, ListX_ElemX ) ) {
9403|        app->m_UndoBuf->AllocNewStep( (CadPrim*)p2->p,
9404|          ((CadPrim*)p->p)->GetNewCopy( &app->m_file.m_prims ), NULL, NULL,
9405|          app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
9406|        p2 = ListX_Elem_getNextT( p2, ListX_ElemX );
9407|      }
9408|      ListX_toEmptyDelete( &m_MultiBefore, ListX_ElemX, NULL );
9409|      delete  m_BeforePrim;
9410|      app->m_UndoBuf->EndMulti();
9411|    }
9412|    m_BeforePrim = NULL;
9413|  }
9414|
9415|  SetScrollSize();
9416|}
9417|
9418|
9419| 
9420|BOOL CChildView::PreTranslateMessage(MSG* pMsg) 
9421|{
9422|#ifdef  SvgCats_DirectInput
9423|  switch ( pMsg->message ) {
9424|
9425|    case WM_CHAR:
9426|{
9427|  CSVGCatApp*   app = (CSVGCatApp*)AfxGetApp();
9428|  CMainFrame*  frame = (CMainFrame*)GetParent()->GetParent();
9429|
9430|  if ( ! m_bDrag ) {
9431|     /* CatsEditor */
9432|     if ( m_HoldPrim != NULL && m_HoldPrim->GetTypeID() == Text_Box_TypeID ) {
9433|       Text_Box*  text = (Text_Box*) m_HoldPrim;
9434|       text->m_Text += pMsg->wParam;
9435|       Redraw(FALSE);
9436|     }
9437|  }
9438|  return  TRUE;
9439|}
9440|
9441|    case WM_KEYDOWN:
9442|      switch ( pMsg->wParam ) {
9443|        case VK_UP:
9444|        case VK_DOWN:
9445|        case VK_LEFT:
9446|        case VK_RIGHT:
9447|          break;
9448|      }
9449|  }
9450|#endif
9451|
9452|	return CScrollView ::PreTranslateMessage(pMsg);
9453|}
9454|
9455| 
9456|