/*! クリップボードの文字列を挿入する・いわゆる貼り付け @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] pXdot 今のドット位置を受けて戻す @param[in] dLine 今の行数 @return HRESULT 終了状態コード */ HRESULT DocRightSlide( PINT pXdot, INT dLine ) { UINT_PTR iLines; INT iTop, iBottom, i; INT dSliDot, dRitDot, dPaDot, dInBgn; INT dMozi, dLefDot, dAdDot; BOOLEAN bFirst = TRUE; LPTSTR ptBuffer = NULL; LINE_ITR itLine; TRACE( TEXT("右寄せ") ); // 右寄せ限界確認 dSliDot = InitParamValue( INIT_LOAD, VL_RIGHT_SLIDE, 790 ); // 範囲確認 iLines = DocNowFilePageLineCount( ); iTop = (*gitFileIt).vcCont.at( gixFocusPage ).dSelLineTop; iBottom = (*gitFileIt).vcCont.at( gixFocusPage ).dSelLineBottom; if( 0 > iTop ) iTop = 0; if( 0 > iBottom ) iBottom = iLines - 1; ViewSelPageAll( -1 ); // 選択範囲無くなる dRitDot = DocPageMaxDotGet( iTop, iBottom ); // 一番右のドット確認 dPaDot = dSliDot - dRitDot; if( 0 > dPaDot ) { NotifyBalloonExist( TEXT("はみ出してるみたい"), TEXT("失敗"), NIIF_ERROR ); return E_FAIL; } itLine = (*gitFileIt).vcCont.at( gixFocusPage ).ltPage.begin(); std::advance( itLine, iTop ); // 位置合わせ for( i = iTop; iBottom >= i; i++, itLine++ ) { dAdDot = dPaDot; // 行頭の開き状態を確認 dLefDot = LayerHeadSpaceCheck( &(itLine->vcLine), &dMozi ); if( 0 < dLefDot ) { dAdDot += dLefDot; // 手前に空白があるなら、その分含めてずらし用スペースを計算 DocRangeDeleteByMozi( 0, i, 0, dMozi, &bFirst ); bFirst = FALSE; } // 先頭からうめちゃう dInBgn = 0; ptBuffer = DocPaddingSpaceWithPeriod( dAdDot, NULL, NULL, NULL, TRUE ); DocInsertString( &dInBgn, &i, NULL, ptBuffer, 0, bFirst ); bFirst = FALSE; FREE(ptBuffer); ViewRedrawSetLine( i ); } // キャレット位置適当に調整 *pXdot = 0; DocLetterPosGetAdjust( pXdot, dLine, 0 ); // キャレット位置適当に調整 ViewDrawCaret( *pXdot, dLine, 1 ); DocPageInfoRenew( -1, 1 ); return S_OK; }
/*! 頁番号挿入のアレ @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; }
/*! 各行の末端から800くらいまでを、指定した文字で埋める。 @param[in] ptFill 埋め文字列 */ HRESULT DocScreenFill( LPTSTR ptFill ) { UINT_PTR dLines, dRiDot, cchSize; BOOLEAN bSel = TRUE, bFirst; INT iTop, iBottom, i, iUnt, j, remain; INT nDot, sDot, mDot; LPTSTR ptBuffer; wstring wsBuffer; // 現在行数と、右ドット数・ルーラ位置を使う dLines = DocNowFilePageLineCount( ); dRiDot = gdRightRuler; // 選択範囲あるならそっち優先。ないなら画面全体 iTop = (*gitFileIt).vcCont.at( gixFocusPage ).dSelLineTop; iBottom = (*gitFileIt).vcCont.at( gixFocusPage ).dSelLineBottom; if( 0 > iTop || 0 > iBottom ){ iTop = 0; iBottom = dLines - 1; bSel = FALSE; } ViewSelPageAll( -1 ); // 選択範囲無くなる // 埋め文字列の幅 mDot = ViewStringWidthGet( ptFill ); bFirst = TRUE; // 各行毎に追加する感じで for( i = iTop; iBottom >= i; i++ ) { nDot = DocLineParamGet( i , NULL, NULL ); // 呼び出せば中で面倒みてくれる sDot = dRiDot - nDot; // 残りドット if( 0 >= sDot ){ continue; } // 右端超えてるならなにもせんでいい iUnt = (sDot / mDot) + 1; // 埋める分・はみ出し・適当で良い // 入れる文字列作成 wsBuffer.clear( ); for( j = 0; iUnt > j; j++ ){ wsBuffer += wstring( ptFill ); } cchSize = wsBuffer.size( ) + 1; ptBuffer = (LPTSTR)malloc( cchSize * sizeof(TCHAR) ); StringCchCopy( ptBuffer, cchSize, wsBuffer.c_str( ) ); // 末端にブチこむ DocInsertString( &nDot, &i, NULL, ptBuffer, 0, bFirst ); bFirst = FALSE; FREE(ptBuffer); DocBadSpaceCheck( i ); // ここで空白チェキ・あまり意味はないが色換えは必要 } if( !(bSel) ) // 非選択状態で { remain = 40 - dLines; // とりあえず40行とする if( 0 < remain ) // 足りないなら { DocAdditionalLine( remain, &bFirst ); // とりあえず改行して dLines = DocNowFilePageLineCount( ); iUnt = (dRiDot / mDot) + 1; // 埋める分・はみ出し・適当で良い // 入れる文字列作成 wsBuffer.clear( ); for( j = 0; iUnt > j; j++ ){ wsBuffer += wstring( ptFill ); } cchSize = wsBuffer.size( ) + 1; ptBuffer = (LPTSTR)malloc( cchSize * sizeof(TCHAR) ); StringCchCopy( ptBuffer, cchSize, wsBuffer.c_str( ) ); iTop = iBottom + 1; iBottom = dLines - 1; for( i = iTop; iBottom >= i; i++ ) { // 末端にブチこむ nDot = DocLineParamGet( i , NULL, NULL ); // 多分0のハズ DocInsertString( &nDot, &i, NULL, ptBuffer, 0, bFirst ); bFirst = FALSE; DocBadSpaceCheck( i ); // ここで空白チェキ・あまり意味はないが色換えは必要 } FREE(ptBuffer); } } DocPageInfoRenew( -1, 1 ); return S_OK; }