/*! 頁を削除・ファイルコア函数 @param[in] iPage 削除する頁の番号 @param[in] iBack −1無視 0〜削除したあと移動する頁指定 @return HRESULT 終了状態コード */ HRESULT DocPageDelete( INT iPage, INT iBack ) { INT i, iNew; PAGE_ITR itPage; if( 1 >= DocNowFilePageCount( ) ) return E_ACCESSDENIED; #ifdef DO_TRY_CATCH try{ #endif // ここでバックアップを? // 街頭位置までイテレータをもっていく itPage = (*gitFileIt).vcCont.begin( ); for( i = 0; iPage > i; i++ ){ itPage++; } FREE( itPage->ptRawData ); SqnFreeAll( &(itPage->stUndoLog) ); // アンドゥログ削除 (*gitFileIt).vcCont.erase( itPage ); // さっくり削除 gixFocusPage = -1; // 頁選択無効にする PageListDelete( iPage ); if( 0 <= iBack ) // 戻り先指定 { iNew = iBack; } else { iNew = iPage - 1; // 削除したら一つ前の頁へ if( 0 > iNew ) iNew = 0; } DocPageChange( iNew ); // 削除したら頁移動 #ifdef DO_TRY_CATCH } catch( exception &err ){ return ETC_MSG( err.what(), E_FAIL ); } catch( ... ){ return ETC_MSG( ("etc error"), E_FAIL ); } #endif return S_OK; }
/*! ホットキーによる投下の調整 @return HRESULT 終了状態コード */ HRESULT DocThreadDropCopy( VOID ) { CHAR acBuf[260]; TCHAR atTitle[64], atInfo[256]; INT cbSize, maxPage;//, dFocusBuf; LPVOID pcString = NULL; // dFocusBuf = gixFocusPage; // 現在頁を一旦待避させて // gixFocusPage = gixDropPage; // 投下用頁にして // cbSize = DocPageTextAllGetAlloc( D_SJIS, &pcString ); cbSize = DocPageTextGetAlloc( gitFileIt, gixDropPage, D_SJIS, &pcString, FALSE ); // gixFocusPage = dFocusBuf; // 終わったら戻す TRACE( TEXT("%d 頁をコピー"), gixDropPage ); DocClipboardDataSet( pcString, cbSize, D_SJIS ); ZeroMemory( acBuf, sizeof(acBuf) ); StringCchCopyNA( acBuf, 260, (LPCSTR)pcString, 250 ); ZeroMemory( atInfo, sizeof(atInfo) ); MultiByteToWideChar( CP_ACP, 0, acBuf, (INT)strlen(acBuf), atInfo, 256 ); StringCchPrintf( atTitle, 64, TEXT("%d 頁をコピーしたよ"), gixDropPage + 1 ); NotifyBalloonExist( atInfo, atTitle, NIIF_INFO ); FREE( pcString ); gixDropPage++; // 次の頁へ maxPage = DocNowFilePageCount( ); if( maxPage <= gixDropPage ) gixDropPage = 0; // 最終頁までイッたら先頭に戻る return S_OK; }
/*! 現在のユニコード数値参照の具合に合わせて文字列をチェインジ @return HRESULT 終了状態コード */ HRESULT UnicodeRadixExchange( LPVOID pVoid ) { INT_PTR iPage, iLine, iMozi, dP, dL, dM; TCHAR cchMozi; CHAR acSjis[10]; LINE_ITR itLine; iPage = DocNowFilePageCount( ); for( dP = 0; iPage > dP; dP++ ) // 全頁 { iLine = (*gitFileIt).vcCont.at( dP ).ltPage.size( ); itLine = (*gitFileIt).vcCont.at( dP ).ltPage.begin(); for( dL = 0; iLine > dL; dL++, itLine++ ) // 全行 { iMozi = itLine->vcLine.size( ); for( dM = 0; iMozi > dM; dM++ ) // 全字 { if( itLine->vcLine.at( dM ).mzStyle & CT_CANTSJIS ) { cchMozi = itLine->vcLine.at( dM ).cchMozi; if( gbUniRadixHex ){ StringCchPrintfA( acSjis, 10, ("&#x%X;"), cchMozi ); } else{ StringCchPrintfA( acSjis, 10, ("&#%d;"), cchMozi ); } StringCchCopyA( itLine->vcLine.at( dM ).acSjis, 10, acSjis ); // TODO: バイト数再計算が必要 } } } } return S_OK; }
/*! 頁を表示する @param[in] iViewPage 頁番号・−1なら全頁 */ HRESULT PreviewPageWrite( INT iViewPage ) { HRESULT hRslt; VARIANT *param; SAFEARRAY *sfArray; UINT_PTR szSize; INT szCont, bstrLen; INT_PTR iPage, i; LPSTR pcContent; CHAR acSeper[MAX_STRING]; BSTR bstr; string asString; SYSTEMTIME stTime; hRslt = S_OK; giViewMode = iViewPage; if( !(gpcHtmlHdr) ) { NotifyBalloonExist( TEXT("プレビュー用テンプレートファイルが見つからないよ"), TEXT("お燐からのお知らせ"), NIIF_ERROR ); return E_HANDLE; } // 表示内容をSJISでつくる GetLocalTime( &stTime ); if( 0 > iViewPage ) // 全プレ { asString = string( gpcHtmlHdr ); iPage = DocNowFilePageCount( ); // 頁数確認して for( i = 0; iPage > i; i++ ) { StringCchPrintfA( acSeper, MAX_STRING, gacResHeaderFmt, (i+1), stTime.wYear, stTime.wMonth, stTime.wDay, gcacWeek[stTime.wDayOfWeek], stTime.wHour, stTime.wMinute, stTime.wSecond ); pcContent = DocPageTextPreviewAlloc( i, &szCont ); asString += string( acSeper ); asString += string( pcContent ); asString += string( gacResFooterFmt ); FREE(pcContent); } asString += string( gpcHtmlFtr ); } else { StringCchPrintfA( acSeper, MAX_STRING, gacResHeaderFmt, (iViewPage+1), stTime.wYear, stTime.wMonth, stTime.wDay, gcacWeek[stTime.wDayOfWeek], stTime.wHour, stTime.wMinute, stTime.wSecond ); pcContent = DocPageTextPreviewAlloc( iViewPage, &szCont ); asString = string( gpcHtmlHdr ); asString += string( acSeper ); asString += string( pcContent ); asString += string( gacResFooterFmt ); asString += string( gpcHtmlFtr ); FREE(pcContent); } // BSTRに必要なサイズ確認 szSize = asString.size( ); bstrLen = MultiByteToWideChar( CP_ACP, 0, asString.c_str( ), szSize, NULL, 0 ); // バッファを確保 bstr = SysAllocStringLen( NULL, bstrLen ); // BSTRにブチこむ MultiByteToWideChar( CP_ACP, 0, asString.c_str( ), szSize, bstr, bstrLen ); sfArray = SafeArrayCreateVector( VT_VARIANT, 0, 1 ); if (sfArray == NULL || gpDocument2 == NULL) { goto cleanup; } hRslt = SafeArrayAccessData(sfArray, (LPVOID*)¶m ); param->vt = VT_BSTR; param->bstrVal = bstr; hRslt = SafeArrayUnaccessData(sfArray); hRslt = gpDocument2->writeln(sfArray); hRslt = gpDocument2->close( ); cleanup: if( bstr ) { SysFreeString( bstr ); hRslt = SafeArrayAccessData( sfArray, (LPVOID*)¶m ); param->vt = VT_BSTR; param->bstrVal = NULL; hRslt = SafeArrayUnaccessData( sfArray ); } if( sfArray ){ SafeArrayDestroy( sfArray ); } return hRslt; }
/*! ページ追加処理・ファイルコア函数 @param[in] iAdding この指定ページの次に追加・-1で末端に追加 @return INT 新規作成したページ番号 */ INT DocPageCreate( INT iAdding ) { INT_PTR iTotal, iNext; UINT_PTR iAddPage = 0; INT i; ONELINE stLine; ONEPAGE stPage; PAGE_ITR itPage; #ifdef DO_TRY_CATCH try{ #endif ZeroONELINE( &stLine ); // 新規作成したら、壱行目が0文字な枠を作る // こっちもZeroONEPAGEとかにまとめるか ZeroMemory( stPage.atPageName, sizeof(stPage.atPageName) ); // stPage.dDotCnt = 0; stPage.dByteSz = 0; stPage.ltPage.clear( ); stPage.ltPage.push_back( stLine ); // 1頁の枠を作って stPage.dSelLineTop = -1; // 無効は−1を注意 stPage.dSelLineBottom = -1; // stPage.ptRawData = NULL; SqnInitialise( &(stPage.stUndoLog) ); // 今の頁の次に作成 iTotal = DocNowFilePageCount( ); if( 0 <= iAdding ) { iNext = iAdding + 1; // 次の頁 if( iTotal <= iNext ){ iNext = -1; } // 全頁より多いなら末端指定 } else { iNext = -1; } if( 0 > iNext ) // 末尾に追加 { (*gitFileIt).vcCont.push_back( stPage ); // ファイル構造体に追加 iAddPage = DocNowFilePageCount( ); iAddPage--; // 末端に追加したんだから、個数数えて−1したら0インデックス番号 } else { itPage = (*gitFileIt).vcCont.begin( ); for( i = 0; iNext > i; i++ ){ itPage++; } (*gitFileIt).vcCont.insert( itPage, stPage ); iAddPage = iNext; } #ifdef DO_TRY_CATCH } catch( exception &err ){ return ETC_MSG( err.what(), 0 ); } catch( ... ){ return ETC_MSG( ("etc error"), 0 ); } #endif return iAddPage; // 追加したページ番号 }
/*! 頁番号挿入のアレ @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; }
/*! 抽出対象領域を取り出す @param[in] hInst 実存値 @return HRESULT 終了状態コード */ HRESULT DocExtractExecute( HINSTANCE hInst ) { INT dOffDot, dCount; BOOLEAN bLnFirst, bMzFirst, bIsVoid; LPTSTR ptSpace, ptString; UINT_PTR cch;//, i; LINE_ITR itLnFirst, itLnLast, itLnErate, itLnEnd; LETR_ITR itMozi, itMzEnd; wstring wsBuffer; if( 0 >= DocNowFilePageCount( ) ) return S_FALSE; // 開始行と終止行・オフセット量を検索 itLnErate = (*gitFileIt).vcCont.at( gixFocusPage ).ltPage.begin(); itLnEnd = (*gitFileIt).vcCont.at( gixFocusPage ).ltPage.end(); itLnFirst = itLnErate; itLnLast = itLnEnd; dOffDot = DocPageMaxDotGet( -1, -1 ); // MAX位置を初期にしとけばおk bLnFirst = TRUE; for( ; itLnEnd != itLnErate; itLnErate++ ) // 行サーチ { itMozi = itLnErate->vcLine.begin(); itMzEnd = itLnErate->vcLine.end(); dCount = 0; for( ; itMzEnd != itMozi; itMozi++ ) // 文字サーチ { if( CT_SELECT & itMozi->mzStyle ) // 選択状態発見 { if( bLnFirst ) // 最初の行が未発見であれば { itLnFirst = itLnErate; // 今の行を記録する bLnFirst = FALSE; } itLnLast = itLnErate; // 選択状態があるので終止行を更新 // そこまでのオフセット量よりさらに小さければ更新 if( dOffDot > dCount ) dOffDot = dCount; break; // 次の行に移動 } dCount += itMozi->rdWidth; // そこまでのドット数をため込む } } if( itLnLast != itLnEnd ) itLnLast++; // 終止の次の行を示しておく if( bLnFirst ) return S_FALSE; // 選択範囲がなかったら死にます wsBuffer.clear(); // 開始行から内容を確保していく for( itLnErate = itLnFirst; itLnLast != itLnErate; itLnErate++ ) // 行サーチ { itMozi = itLnErate->vcLine.begin(); itMzEnd = itLnErate->vcLine.end(); bMzFirst = TRUE; bIsVoid = FALSE; dCount = 0; for( ; itMzEnd != itMozi; itMozi++ ) // 文字サーチ { if( CT_SELECT & itMozi->mzStyle ) // 選択状態発見 { if( bIsVoid ) // 直前まで未選択状態 { if( bMzFirst ) // 最初の空白部分であれば { dCount -= dOffDot; // オフセットする if( 0 > dCount ) dCount = 0; bMzFirst = FALSE; } // 埋めSpaceを作る・不可ならNULLが返る ptSpace = DocPaddingSpaceMake( dCount ); if( ptSpace ) { wsBuffer += ptSpace; //StringCchLength( ptSpace, STRSAFE_MAX_CCH, &cch ); //for( i = 0; cch > i; i++ ) //{ // wsBuffer += (ptSpace[i]); //} FREE(ptSpace); } } wsBuffer += itMozi->cchMozi; dCount = 0; // リセット bIsVoid = FALSE; } else { dCount += itMozi->rdWidth; // そこまでのドット数をため込む bIsVoid = TRUE; } } wsBuffer += CH_CRLFW; // 改行追加 } // この時点で、wsBufferに全体が入っているはず cch = wsBuffer.size( ) + 1; ptString = (LPTSTR)malloc( cch * sizeof(TCHAR) ); StringCchCopy( ptString, cch, wsBuffer.c_str( ) ); if( hInst ) // 実存してるならレイヤボックスへ { LayerBoxVisibalise( hInst, ptString, 0x00 ); } else // ないならクルッペボード { DocClipboardDataSet( ptString, cch * sizeof(TCHAR), D_UNI ); } FREE(ptString); return S_OK; }