/*! クリップボードの文字列を挿入する・いわゆる貼り付け @param[in,out] pNowDot 今のキャレットのドット位置 @param[in,out] pdLine 対象の行番号・絶対0インデックスか @param[in,out] pdMozi 今のキャレットの文字数 @param[in] bSqMode 非0強制矩形貼付・内容増やすならFlagに注意 @return 0壱行ですんだ 非0複数行に渡った */ INT DocInputFromClipboard( PINT pNowDot, PINT pdLine, PINT pdMozi, UINT bSqMode ) { LPTSTR ptString = NULL; UINT cchSize, dStyle = 0, i, j; INT dCrLf, dTop, dBtm; BOOLEAN bSelect; UINT dSqSel, iLines; // クリップボードからデータを頂く ptString = DocClipboardDataGet( &dStyle ); if( !(ptString) ) { NotifyBalloonExist( TEXT("テキストじゃないみたい。\t\n貼り付けられないよ。"), TEXT("お燐からのお知らせ"), NIIF_INFO ); return 0; } StringCchLength( ptString, STRSAFE_MAX_CCH, &cchSize ); // タブをヌく for( i = 0; cchSize > i; ) { if( CC_TAB == ptString[i] ) { for( j = i; cchSize > j; j++ ) { ptString[j] = ptString[j+1]; } cchSize--; continue; } i++; } bSelect = IsSelecting( &dSqSel ); // 選択状態であるか if( bSelect ) { DocSelRangeGet( &dTop, &dBtm ); dCrLf = DocSelectedDelete( pNowDot, pdLine, dSqSel, TRUE ); if( dCrLf ) // 処理した行以降全取っ替え { iLines = DocPageParamGet( NULL, NULL ); // 再計算も要るかも・・・ for( i = *pdLine; iLines >= i; i++ ){ ViewRedrawSetLine( i ); } } else{ ViewRedrawSetLine( *pdLine ); } } if( bSqMode ) dStyle |= D_SQUARE; // 矩形挿入として扱うか dCrLf = DocInsertString( pNowDot, pdLine, pdMozi, ptString, dStyle, TRUE ); FREE( ptString ); DocPageInfoRenew( -1, 1 ); return dCrLf; }
/*! 選択されたユーザ定義アイテムの処理 @param[in] hWnd 多分メインウインドウハンドル @param[in] idNum アイテム番号0〜15 @return HRESULT 終了状態コード */ HRESULT UserDefItemInsert( HWND hWnd, UINT idNum ) { INT iLines, yLine, iMinus, i, dmyDot; INT_PTR dNeedLine; LPTSTR ptText; BOOLEAN bFirst = TRUE; // はみ出したらアウツ! if( gdItemCnt <= idNum ) return E_OUTOFMEMORY; // 今のカーソル行から、行先頭に、各行の内容を挿入していく yLine = gdDocLine; dNeedLine = gstUserItem[idNum].vcUnits.size( ); // まずは頁行数かくぬん iLines = DocPageParamGet( NULL , NULL ); // 行数確認・入れ替えていけるか // 全体行数より、追加行数が多かったら、改行増やす if( iLines < (dNeedLine + yLine) ) { iMinus = (dNeedLine + yLine) - iLines; // 追加する行数 DocAdditionalLine( iMinus, &bFirst );// bFirst = FALSE; // この頁の行数取り直し iLines = DocPageParamGet( NULL , NULL ); // 再計算いるか? } for( i = 0; dNeedLine > i; i++, yLine++ ) { ptText = UserDefTextLineAlloc( idNum, i ); dmyDot = 0; DocInsertString( &dmyDot, &yLine, NULL, ptText, 0, bFirst ); bFirst = FALSE; FREE(ptText); } return S_OK; }
/*! 指定行の内容を削除する・改行はそのまま @param[in] yLine 対象の行番号 @param[in] pFirst アンドゥの非0初めてのグループ 0続きの処理 @return HRESULT 終了状態コード */ HRESULT DocLineErase( INT yLine, PBOOLEAN pFirst ) { INT dLines, iMozis, i; INT_PTR cbSize, cchSize; LPTSTR ptBuffer; wstring wsString; LINE_ITR itLine; wsString.clear( ); dLines = DocNowFilePageLineCount( );//DocPageParamGet( NULL, NULL ); // 行数確認 if( dLines <= yLine ) return E_OUTOFMEMORY; // はみ出し確認 DocLineParamGet( yLine, &iMozis, NULL ); // 指定行の文字数確保 if( 0 >= iMozis ) return E_ABORT; // 文字がないならすること無い itLine = (*gitFileIt).vcCont.at( gixFocusPage ).ltPage.begin(); std::advance( itLine, yLine ); for( i = 0; iMozis > i; i++ ) // 全文字を確保 { wsString += itLine->vcLine.at( i ).cchMozi; } cchSize = wsString.size( ) + 1; // NULLターミネータ分足す cbSize = cchSize * sizeof(TCHAR); // ユニコードなのでバイト数は2倍である ptBuffer = (LPTSTR)malloc( cbSize ); ZeroMemory( ptBuffer, cbSize ); StringCchCopy( ptBuffer, cchSize, wsString.c_str( ) ); SqnAppendString( &((*gitFileIt).vcCont.at( gixFocusPage ).stUndoLog), DO_DELETE, ptBuffer, 0, yLine, *pFirst ); *pFirst = FALSE; // 削除処理 itLine->vcLine.clear(); DocLineParamGet( yLine, NULL, NULL ); // 行内容の再計算 DocPageParamGet( NULL, NULL ); // 再計算 DocBadSpaceCheck( yLine ); // リセットに必要 ViewRedrawSetLine( yLine ); // 要らないかも return S_OK; }
/*! 頁を作って内容をぶち込む @param[in] ptName 項目の名前・無い時はNULL @param[in] ptCont 項目の内容 @param[in] cchSize 内容の文字数 @return UINT 特に意味なし */ UINT CALLBACK DocPageLoad( LPTSTR ptName, LPCTSTR ptCont, INT cchSize ) { gixFocusPage = DocPageCreate( -1 ); // 頁を作成 PageListInsert( gixFocusPage ); // ページリストビューに追加 // 新しく作ったページにうつる if( ptName ){ DocPageNameSet( ptName ); } // 名前をセットしておく (*gitFileIt).vcCont.at( gixFocusPage ).ptRawData = (LPTSTR)malloc( (cchSize+2) * sizeof(TCHAR) ); ZeroMemory( (*gitFileIt).vcCont.at( gixFocusPage ).ptRawData, (cchSize+2) * sizeof(TCHAR) ); //HRESULT hRslt = StringCchCopy( (*gitFileIt).vcCont.at( gixFocusPage ).ptRawData, (cchSize+2), ptCont ); // バッファに文字列を保存だけしておく DocPageParamGet( NULL, NULL ); // 再計算しちゃう・遅延読込ヒット return 1; }
/*! 文字列(矩形もアリ)を挿入する @param[in,out] pNowDot 今のキャレットのドット位置 @param[in,out] pdLine 対象の行番号・絶対0インデックスか @param[in,out] pdMozi 今のキャレットの文字数・NULLでもおk @param[in] ptText 挿入する文字列 @param[in] dStyle 矩形かどうか、不可視特別か @param[in] bFirst アンドゥ用・これが最初のアクションか @return 0壱行ですんだ 非0複数行に渡った */ INT DocInsertString( PINT pNowDot, PINT pdLine, PINT pdMozi, LPCTSTR ptText, UINT dStyle, BOOLEAN bFirst ) { INT dBaseDot, dBaseLine, dNeedLine; INT dCrLf, i, dLastLine; UINT_PTR cchSize; LPPOINT pstPoint; dBaseDot = *pNowDot; dBaseLine = *pdLine; dLastLine = *pdLine; if( !(ptText) ) return 0; // 挿入文字列がないなら直ぐ終わってよい StringCchLength( ptText, STRSAFE_MAX_CCH, &cchSize ); if( dStyle & D_SQUARE ) // 矩形用 { // 使う行数 dNeedLine = DocStringInfoCount( ptText, cchSize, NULL, NULL ); bFirst = DocSquareAddPreMod( *pNowDot, *pdLine, dNeedLine, bFirst ); // 中でアンドゥ追加までやる。 pstPoint = NULL; // NULL化必須 dCrLf = DocSquareAdd( pNowDot, pdLine, ptText, cchSize, &pstPoint ); // 貼付前の整形を含めて1Groupとして扱う必要がある SqnAppendSquare( &((*gitFileIt).vcCont.at( gixFocusPage ).stUndoLog), DO_INSERT, ptText, pstPoint, dCrLf, bFirst ); bFirst = FALSE; FREE( pstPoint ); dLastLine = *pdLine; } else { // この中で改行とか面倒見る dCrLf = DocStringAdd( pNowDot, pdLine, ptText, cchSize ); SqnAppendString( &((*gitFileIt).vcCont.at( gixFocusPage ).stUndoLog), DO_INSERT, ptText, dBaseDot, dBaseLine, bFirst ); bFirst = FALSE; dLastLine = DocPageParamGet( NULL, NULL );//再計算必要か? } if( dCrLf ) { for( i = dBaseLine; dLastLine >= i; i++ ){ ViewRedrawSetLine( i ); } } else { ViewRedrawSetLine( *pdLine ); } if( pdMozi ){ *pdMozi = DocLetterPosGetAdjust( pNowDot, *pdLine , 0 ); } // 今の文字位置を確認 // ヤバイ状態のときは操作しないようにする if( !(D_INVISI & dStyle) ) ViewDrawCaret( *pNowDot, *pdLine, TRUE ); return dCrLf; }
/*! 頁番号挿入のアレ @param[in] hInst アプリの実存 @param[in] hWnd 親ウインドウハンドル・NULLで破壊処理 @return HRESULT 終了状態コード */ HRESULT DocPageNumInsert( HINSTANCE hInst, HWND hWnd ) { INT dNowPageBuffer; INT iLine, iDot; INT_PTR iRslt, maxPage, iNow; UINT ixNumber; BOOLEAN bFirst = TRUE; TCHAR atText[MAX_PATH]; PAGENUMINFO stInfo; // 今の頁を待避 dNowPageBuffer = gixFocusPage; maxPage = DocNowFilePageCount( ); // 頁数を確認 ZeroMemory( &stInfo, sizeof(PAGENUMINFO) ); stInfo.dStartNum = 1; // 設定を確認 stInfo.bInUnder = InitParamValue( INIT_LOAD, VL_PAGE_UNDER, BST_UNCHECKED ); // 頁番号を最下行に挿入するか stInfo.bOverride = InitParamValue( INIT_LOAD, VL_PAGE_OVWRITE, BST_UNCHECKED ); // 該当行の内容を削除して上書するか // 文字列フォーマット StringCchCopy( stInfo.atStyle, MAX_PATH, TEXT("%u") ); // デフォ設定 InitParamString( INIT_LOAD, VS_PAGE_FORMAT, stInfo.atStyle ); iRslt = DialogBoxParam( hInst, MAKEINTRESOURCE(IDD_PAGENUMBER_DLG), hWnd, PageNumDlgProc, (LPARAM)(&stInfo) ); if( IDOK == iRslt ) // 挿入する { #pragma message("ディレイロードしたら、頁番号挿入がおかしくなるはず") ixNumber = stInfo.dStartNum; // 開始番号について InitParamString( INIT_SAVE, VS_PAGE_FORMAT, stInfo.atStyle ); // 設定を保存 InitParamValue( INIT_SAVE, VL_PAGE_UNDER, stInfo.bInUnder ); InitParamValue( INIT_SAVE, VL_PAGE_OVWRITE, stInfo.bOverride ); for( iNow = 0; maxPage > iNow; iNow++, ixNumber++ ) { StringCchPrintf( atText, MAX_PATH, stInfo.atStyle, ixNumber ); if( NowPageInfoGet( iNow, NULL ) ) // ディレってないなら0 { // ディレイ文字列を操作するか DocDelayPageNumInsert( gitFileIt, iNow, &stInfo, atText ); // 展開する・頁が多いと重い・しなくていい //DocDelayPageLoad( gitFileIt, iNow ); } else { gixFocusPage = iNow; // 内部操作 if( stInfo.bInUnder ) // 頁最下部に挿入 { if( stInfo.bOverride ) // 該当行消して挿入である { iLine = DocPageParamGet( NULL, NULL ); iLine--; if( 0 > iLine ){ iLine = 0; } DocLineErase( iLine , &bFirst ); // 中でアンドゥ操作変換 } else { iLine = DocAdditionalLine( 1, &bFirst );// bFirst = FALSE; } } else // 壱行目に挿入 { iDot = 0; iLine = 0; if( stInfo.bOverride ) // 該当行消して挿入である { DocLineErase( 0 , &bFirst ); // 中でアンドゥ操作変換 } else { DocInsertString( &iDot, &iLine, NULL, CH_CRLFW, 0, bFirst ); bFirst = FALSE; } iLine = 0; } iDot = 0; // 頁番号の内容挿入 DocInsertString( &iDot, &iLine, NULL, atText, 0, bFirst ); bFirst = FALSE; } } // 頁元に戻す gixFocusPage = dNowPageBuffer; ViewRedrawSetLine( -1 ); } return S_OK; }
/*! ページ全体の選択状態をON/OFFする @param[in] dForce 0无 +選択状態 ー選択解除 @return 全体文字数 */ INT DocPageSelStateToggle( INT dForce ) { UINT_PTR iLines, ln, iLetters, mz; UINT dStyle; INT iTotal, iDot, iWid; RECT inRect; LINE_ITR itLine; if( 0 == dForce ) return 0; // 0なら処理しない if( 0 > gixFocusPage ) return 0; // 特殊な状況下では処理しない iTotal = 0; iLines = DocNowFilePageLineCount( ); itLine = (*gitFileIt).vcCont.at( gixFocusPage ).ltPage.begin(); for( ln = 0; iLines > ln; ln++, itLine++ ) { iDot = 0; // そこまでのドット数をため込む inRect.top = ln * LINE_HEIGHT; inRect.bottom = inRect.top + LINE_HEIGHT; iLetters = itLine->vcLine.size( ); // この行の文字数確認して // 壱文字ずつ、全部をチェキっていく for( mz = 0; iLetters > mz; mz++ ) { // 直前の状態 dStyle = itLine->vcLine.at( mz ).mzStyle; iWid = itLine->vcLine.at( mz ).rdWidth; inRect.left = iDot; inRect.right = iDot + iWid; if( 0 < dForce ) { itLine->vcLine.at( mz ).mzStyle |= CT_SELECT; if( !(dStyle & CT_SELECT) ){ ViewRedrawSetRect( &inRect ); } } else { itLine->vcLine.at( mz ).mzStyle &= ~CT_SELECT; if( dStyle & CT_SELECT ){ ViewRedrawSetRect( &inRect ); } } iDot += iWid; iTotal++; } // 壱行終わったら末尾状況確認。改行・本文末端に改行はない・選択のときのみ dStyle = itLine->dStyle; inRect.left = iDot; inRect.right = iDot + 20; // 改行描画エリア・大体これくらい if( 0 < dForce ) { if( iLines > ln+1 ) { itLine->dStyle |= CT_SELRTN; if( !(dStyle & CT_SELRTN) ){ ViewRedrawSetRect( &inRect ); } } } else { itLine->dStyle &= ~CT_SELRTN; if( dStyle & CT_SELRTN ){ ViewRedrawSetRect( &inRect ); } } } if( 0 < dForce ) // 頁全体のバイト数そのものか、非選択なので0 { DocSelRangeSet( 0, iLines - 1 ); DocPageParamGet( NULL, &gdSelByte ); } else { DocSelRangeSet( -1, -1 ); gdSelByte = 0; } DocSelectedByteStatus( ); // ViewRedrawSetLine( -1 ); // 画面表示更新 return iTotal; }