Code sample Home

Implement custom commands

See project "Editor" in the www.kolbasoft.com/LC_Samples

//-----------------------------------------------
void CALLBACK EventProc (HANDLE hEvent)
{
  int EventType;
  HANDLE hLcWnd;
  LcApplication* pApp = (LcApplication*)lcPropGetHandle( hEvent, LC_PROP_EVENT_APPPRM2 );
  if (pApp){
    EventType = lcPropGetInt( hEvent, LC_PROP_EVENT_TYPE );
    switch( EventType ){
      case LC_EVENT_MOUSEMOVE: pApp->OnMouseMove( hEvent );  break;
      case LC_EVENT_WNDVIEW:   pApp->OnWndView( hEvent );  break;
      case LC_EVENT_HELP:      pApp->OnHelp( hEvent );  break;
      case LC_EVENT_ADDSTR:    pApp->OnAddStr( hEvent );  break;
      case LC_EVENT_KEYDOWN:   pApp->OnKeyDown( hEvent ); break;
      case LC_EVENT_ADDCMD:
        // add custom commands
        hLcWnd = lcPropGetHandle( hEvent, LC_PROP_EVENT_WND );
        lcCreateCommand( hLcWnd, CMD_SKETCH, L"Sketch" );
        lcCreateCommand( hLcWnd, CMD_EXPLOD, L"Explod" );
        break;
    }
  }
}

//-----------------------------------------------
void ProcCmdCreate (HANDLE hEvent)
{
  int idCmd = lcPropGetInt( hEvent, LC_PROP_EVENT_INT1 );
  switch( idCmd ){
    case CMD_SKETCH: CmdSketch_Create( hEvent );  break;
    case CMD_EXPLOD: CmdExplod_Create( hEvent );  break;
  }
}
//-----------------------------------------------
void ProcCmdDestroy (HANDLE hEvent)
{
  int idCmd = lcPropGetInt( hEvent, LC_PROP_EVENT_INT1 );
  switch( idCmd ){
    case CMD_SKETCH: CmdSketch_Destroy( hEvent );  break;
    case CMD_EXPLOD: CmdExplod_Destroy( hEvent );  break;
  }
}
//-----------------------------------------------
void ProcCmdStart (HANDLE hEvent)
{
  int idCmd = lcPropGetInt( hEvent, LC_PROP_EVENT_INT1 );
  switch( idCmd ){
    case CMD_SKETCH: CmdSketch_Start( hEvent );  break;
    case CMD_EXPLOD: CmdExplod_Start( hEvent );  break;
  }
}
//-----------------------------------------------
void ProcCmdFinish (HANDLE hEvent)
{
  int idCmd = lcPropGetInt( hEvent, LC_PROP_EVENT_INT1 );
  switch( idCmd ){
    case CMD_SKETCH: CmdSketch_Finish( hEvent );  break;
    case CMD_EXPLOD: CmdExplod_Finish( hEvent );  break;
  }
}
//-----------------------------------------------
void ProcCmdLBDown (HANDLE hEvent)
{
  int idCmd = lcPropGetInt( hEvent, LC_PROP_EVENT_INT1 );
  switch( idCmd ){
    case CMD_SKETCH: CmdSketch_LBDown( hEvent );  break;
    case CMD_EXPLOD: CmdExplod_LBDown( hEvent );  break;
  }
}

//-----------------------------------------------
void ProcCmdLBUp (HANDLE hEvent)
{
  int idCmd = lcPropGetInt( hEvent, LC_PROP_EVENT_INT1 );
  switch( idCmd ){
    case CMD_SKETCH: CmdSketch_LBUp( hEvent );  break;
    case CMD_EXPLOD: CmdExplod_LBUp( hEvent );  break;
  }
}

//-----------------------------------------------
void ProcCmdRBDown (HANDLE hEvent)
{
  int idCmd = lcPropGetInt( hEvent, LC_PROP_EVENT_INT1 );
  switch( idCmd ){
    case CMD_SKETCH: CmdSketch_RBDown( hEvent );  break;
    case CMD_EXPLOD: CmdExplod_RBDown( hEvent );  break;
  }
}

//-----------------------------------------------
void ProcCmdRBUp (HANDLE hEvent)
{
  int idCmd = lcPropGetInt( hEvent, LC_PROP_EVENT_INT1 );
  switch( idCmd ){
    case CMD_SKETCH: CmdSketch_RBUp( hEvent );  break;
    case CMD_EXPLOD: CmdExplod_RBUp( hEvent );  break;
  }
}

//-----------------------------------------------
void ProcCmdMouseMove (HANDLE hEvent)
{
  int idCmd = lcPropGetInt( hEvent, LC_PROP_EVENT_INT1 );
  switch( idCmd ){
    case CMD_SKETCH: CmdSketch_MouseMove( hEvent );  break;
    case CMD_EXPLOD: CmdExplod_MouseMove( hEvent );  break;
  }
}

//-----------------------------------------------
void ProcCmdPaint (HANDLE hEvent)
{
  int idCmd = lcPropGetInt( hEvent, LC_PROP_EVENT_INT1 );
  switch( idCmd ){
    case CMD_SKETCH: CmdSketch_Paint( hEvent );  break;
    case CMD_EXPLOD: CmdExplod_Paint( hEvent );  break;
  }
}

//-----------------------------------------------
void ProcCmdSnap (HANDLE hEvent)
{
  int idCmd = lcPropGetInt( hEvent, LC_PROP_EVENT_INT1 );
  switch( idCmd ){
    case CMD_SKETCH: CmdSketch_Snap( hEvent );  break;
    case CMD_EXPLOD: CmdExplod_Snap( hEvent );  break;
  }
}

//-----------------------------------------------
void CALLBACK EventProcCmd (HANDLE hEvent)
{
  int Mode = lcPropGetInt( hEvent, LC_PROP_EVENT_MODE );
  switch( Mode ){
    case LC_CCMD_CREATE:    ProcCmdCreate( hEvent ); break;
    case LC_CCMD_DESTROY:   ProcCmdDestroy( hEvent ); break;
    case LC_CCMD_START:     ProcCmdStart( hEvent ); break;
    case LC_CCMD_FINISH:    ProcCmdFinish( hEvent ); break;
    case LC_CCMD_LBDOWN:    ProcCmdLBDown( hEvent ); break;
    case LC_CCMD_LBUP:      ProcCmdLBUp( hEvent ); break;
    case LC_CCMD_RBDOWN:    ProcCmdRBDown( hEvent ); break;
    case LC_CCMD_RBUP:      ProcCmdRBUp( hEvent ); break;
    case LC_CCMD_MOUSEMOVE: ProcCmdMouseMove( hEvent ); break;
    case LC_CCMD_PAINT:     ProcCmdPaint( hEvent ); break;
    case LC_CCMD_SNAP:      ProcCmdSnap( hEvent ); break;
  }
}

//-----------------------------------------------
bool LcApplication::Init (HINSTANCE hInst, LPCWSTR szAppDir)
{
  ...
  lcEventSetProc( LC_EVENT_MOUSEMOVE, EventProc, 0, (HANDLE)this );
  lcEventSetProc( LC_EVENT_WNDVIEW  , EventProc, 0, (HANDLE)this );
  lcEventSetProc( LC_EVENT_HELP     , EventProc, 0, (HANDLE)this );
  lcEventSetProc( LC_EVENT_ADDSTR   , EventProc, 0, (HANDLE)this );
  lcEventSetProc( LC_EVENT_KEYDOWN  , EventProc, 0, (HANDLE)this );
  lcEventSetProc( LC_EVENT_ADDCMD   , EventProc, 0, (HANDLE)this );
  lcEventSetProc( LC_EVENT_CCMD, EventProcCmd, 0, (HANDLE)this );

  bInit = lcInitialize();
  ...
}

File "CmdSketch.cpp"
#include "stdafx.h"

static HANDLE hCmd;     // this command
static HANDLE hPtbuf;   // points buffer
static int    nPnts;
static HANDLE hLcWnd;   // CAD window
static HANDLE hBlock;   // current block 
static BOOL   bDraw;    // flag "Pen is down"

//-----------------------------------------------
void CmdSketch_Create (HANDLE hEvent)
{
  hCmd = lcPropGetHandle( hEvent, LC_PROP_EVENT_HCMD );
  hPtbuf = lcPaint_CreatePtbuf();	 // Creates point buffer object
  nPnts = 0;
  hLcWnd = 0;
  hBlock = 0;
  bDraw = false;
}

//-----------------------------------------------
void CmdSketch_Destroy (HANDLE hEvent)
{
  lcPaint_DeletePtbuf( hPtbuf );
  hPtbuf = 0;
  nPnts = 0;
}

//-----------------------------------------------
void CmdSketch_Start (HANDLE hEvent)
{
  bDraw = false;
  hLcWnd = lcPropGetHandle( hEvent, LC_PROP_EVENT_WND );
  hBlock = lcPropGetHandle( hLcWnd, LC_PROP_WND_BLOCK );
  lcPaint_PtbufClear( hPtbuf );
  nPnts = 0;
  lcEventReturnCode( 1 );  // continue command (wait mouse click)
}

//-----------------------------------------------
void CmdSketch_Finish (HANDLE hEvent)
{
}

//-----------------------------------------------
void CmdSketch_LBDown (HANDLE hEvent)
{
  double x, y;

  x = lcPropGetFloat( hEvent, LC_PROP_EVENT_FLOAT1 );
  y = lcPropGetFloat( hEvent, LC_PROP_EVENT_FLOAT2 );
  if (lcPaint_PtbufAddPoint2( hPtbuf, x, y )){
    ++nPnts;
  }
  bDraw = true;
  lcWndRedraw( hLcWnd );
}

//-----------------------------------------------
void CmdSketch_LBUp (HANDLE hEvent)
{
  HANDLE hPline;

  bDraw = false;
  hPline = lcBlockAddPolyline( hBlock, 0, false, false );
  lcPlineFromPtbuf( hPline, hPtbuf );
  lcBlockUpdate( hBlock, false, hPline );
  lcWndRedraw( hLcWnd );
  lcPaint_PtbufClear( hPtbuf );
  nPnts = 0;
}

//-----------------------------------------------
void CmdSketch_RBDown (HANDLE hEvent)
{
  lcCmdExit( hCmd );  // exit command
}

//-----------------------------------------------
void CmdSketch_RBUp (HANDLE hEvent)
{
}

//-----------------------------------------------
void CmdSketch_MouseMove (HANDLE hEvent)
{
  double x, y;

  if (bDraw){
    if (nPnts == 1){
      lcCmdCursorText( hCmd, L"Move cursor to draw" );
    }else{
      lcCmdCursorText( hCmd, L"Release button to stop" );
    }
    x = lcPropGetFloat( hEvent, LC_PROP_EVENT_FLOAT1 );
    y = lcPropGetFloat( hEvent, LC_PROP_EVENT_FLOAT2 );
    if (lcPaint_PtbufAddPoint2( hPtbuf, x, y )){
      ++nPnts;
    }
    lcPaint_DrawPtbuf( hLcWnd, hPtbuf, false );
  }else{
    lcCmdCursorText( hCmd, L"Press left button" );
  }
}

//-----------------------------------------------
void CmdSketch_Paint (HANDLE hEvent)
{
}

//-----------------------------------------------
void CmdSketch_Snap (HANDLE hEvent)
{
}

File "CmdExplod.cpp"
#include "stdafx.h"

static HANDLE hCmd;     // this command
static HANDLE hLcWnd;   // CAD window
static HANDLE hBlock;   // current block 

//-----------------------------------------------
void CmdExplod_Create (HANDLE hEvent)
{
  hCmd = lcPropGetHandle( hEvent, LC_PROP_EVENT_HCMD );
  hLcWnd = 0;
  hBlock = 0;
}

//-----------------------------------------------
void CmdExplod_Destroy (HANDLE hEvent)
{
}

//-----------------------------------------------
void CmdExplod_Start (HANDLE hEvent)
{
  hLcWnd = lcPropGetHandle( hEvent, LC_PROP_EVENT_WND );
  hBlock = lcPropGetHandle( hLcWnd, LC_PROP_WND_BLOCK );
  lcPropPutBool( hCmd, LC_PROP_CMD_CURSORCROSS, false );
  lcEventReturnCode( 1 );  // continue command (wait mouse click)
}

//-----------------------------------------------
void CmdExplod_Finish (HANDLE hEvent)
{
  lcPropPutBool( hCmd, LC_PROP_CMD_CURSORCROSS, true );
}

//-----------------------------------------------
void CmdExplod_LBDown (HANDLE hEvent)
{
  HANDLE hEnt, hEnt2;
  int    nPlines, iPline, nVers, iVer;
  double xc, yc, x0, y0, x1, y1, x2, y2, x3, y3, dx, dy;
  double Angle, Dist;
  BOOL   bRet;

  hEnt = lcWndGetEntByPoint( hLcWnd, -1, -1 );  // at cursor position
  if (hEnt){
    xc = lcPropGetFloat( hEnt, LC_PROP_ENT_XCEN );
    yc = lcPropGetFloat( hEnt, LC_PROP_ENT_YCEN );
    iPline = 0;
    nPlines = lcExpEntity( hEnt, LC_EXP_OUTLINE, false );
    while( 1 ){
      nVers = lcExpGetPline(0);
      if (nVers > 0){
        ++iPline;
        iVer = 0;
        while( 1 ){
          bRet = lcExpGetVertex( &x1, &y1 );
          if (bRet == FALSE){
            // exit vertices cycle
            break;
          }
          // here X,Y has vertex value
          if (iVer > 0){
            hEnt2 = lcBlockAddLine( hBlock, x0, y0, x1, y1 );
            x2 = (x0 + x1) / 2.0;
            y2 = (y0 + y1) / 2.0;
            lcGetPolarPrm( xc, yc, x2, y2, &Angle, &Dist );
            Dist = Dist * 1.5;
            lcGetPolarPoint( xc, yc, Angle, Dist, &x3, &y3 );
            dx = x3 - x2;
            dy = y3 - y2;
            lcEntMove( hEnt2, dx, dy );
          }
          ++iVer;
          x0 = x1;
          y0 = y1;
        }
      }else{
        // exit polylines cycle
        break;
      }
    }
    lcEntErase( hEnt, true );  
    lcBlockUpdate( hBlock, true, 0 );
    lcWndRedraw( hLcWnd );
  }
}

//-----------------------------------------------
void CmdExplod_LBUp (HANDLE hEvent)
{
}

//-----------------------------------------------
void CmdExplod_RBDown (HANDLE hEvent)
{
  lcCmdExit( hCmd );  // exit command
}

//-----------------------------------------------
void CmdExplod_RBUp (HANDLE hEvent)
{
}

//-----------------------------------------------
void CmdExplod_MouseMove (HANDLE hEvent)
{
  lcPaint_DrawPickBox( hLcWnd );
  lcCmdCursorText( hCmd, L"Pick entity" );
}

//-----------------------------------------------
void CmdExplod_Paint (HANDLE hEvent)
{
}

//-----------------------------------------------
void CmdExplod_Snap (HANDLE hEvent)
{
}

Used functions:

lcBlockAddLine
lcBlockAddPolyline
lcBlockUpdate

lcCmdCursorText
lcCmdExit
lcCmdMessage

lcGetPolarPrm
lcGetPolarPoint

lcEntMove
lcEntErase

lcExpEntity
lcExpGetPline
lcExpGetVertex

lcPaint_CreatePtbuf
lcPaint_DrawPickBox
lcPaint_DrawPtbuf
lcPaint_PtbufAddPoint2
lcPaint_PtbufClear

lcPropGetFloat
lcPropGetHandle
lcPropGetInt
lcPropPutBool

lcWndGetEntByPoint
lcWndRedraw

lcCreateCommand
lcEventReturnCode
lcInitialize
lcPlineFromPtbuf