#include "common.h" extern int font_width,font_height; BOOL IsRightTurn(char *pBuf,int i,int now_x){ if(pobj_nv->bRightTurn==0) return 0; if(pobj_nv->iMaxOneLineTextLength-1<=now_x && pBuf[i]!='\r') return 1; return 0; } int GetBufferIndexFromCaretPos(char *pBuf,int now_x,int now_y){ int i,i2; int x,y; // 行の確認 for(i=0,x=0,y=0;;i++,x++){ if(y>=now_y) break; if(pBuf[i]=='\0') return 0; if(IsRightTurn(pBuf,i,x)){ //右端で折り返す y++; x=-1; i--; continue; } if(pBuf[i]=='\t'){ //タブ文字 int tab; tab=pobj_nv->TabSize; if(x%tab==0) i2=tab; else i2=tab-x%tab; x+=i2-1; continue; } else if(IsDBCSLeadByte(pBuf[i])){ //マルチバイト文字 x++; i++; continue; } if(pBuf[i]=='\r'&&pBuf[i+1]=='\n'){ y++; i++; x=-1; } } //列の確認 for(x=0;xTabSize; if(x%tab==0) i2=tab; else i2=tab-x%tab; x+=i2-1; continue; } else if(IsDBCSLeadByte(pBuf[i])){ //マルチバイト文字 x++; i++; continue; } } return i; } void GetCaretPosFromBufferIndex(char *pBuf,int index,POINT *pCaretPos){ int i,i2; pCaretPos->x=0; pCaretPos->y=0; for(i=0;ix++){ if(pBuf[i]=='\0') break; if(IsRightTurn(pBuf,i,pCaretPos->x)){ //右端で折り返す pCaretPos->y++; pCaretPos->x=-1; i--; continue; } if(pBuf[i]=='\r'&&pBuf[i+1]=='\n'){ pCaretPos->x=-1; pCaretPos->y++; i++; continue; } if(IsDBCSLeadByte(pBuf[i])){ i++; pCaretPos->x++; continue; } if(pBuf[i]=='\t'){ //タブ文字 int tab; tab=pobj_nv->TabSize; if(pCaretPos->x%tab==0) i2=tab; else i2=tab-pCaretPos->x%tab; pCaretPos->x+=i2-1; continue; } else if(IsDBCSLeadByte(pBuf[i])){ //マルチバイト文字 pCaretPos->x++; i++; continue; } } } void TextEdit_GetSel(int WndNum,CHARRANGE *pCharRange){ ////////////////////////////////////////// // 選択範囲(バッファインデックス)を取得 ////////////////////////////////////////// extern MDIINFO MdiInfo[MAX_WNDNUM]; pCharRange->cpMin=GetBufferIndexFromCaretPos( MdiInfo[WndNum].pmti->buffer, MdiInfo[WndNum].pmti->StartCaretPos.x, MdiInfo[WndNum].pmti->StartCaretPos.y); if(MdiInfo[WndNum].pmti->StartCaretPos.x==MdiInfo[WndNum].pmti->EndCaretPos.x&& MdiInfo[WndNum].pmti->StartCaretPos.y==MdiInfo[WndNum].pmti->EndCaretPos.y){ //選択されていないとき pCharRange->cpMax=pCharRange->cpMin; } else{ pCharRange->cpMax=GetBufferIndexFromCaretPos( MdiInfo[WndNum].pmti->buffer, MdiInfo[WndNum].pmti->EndCaretPos.x, MdiInfo[WndNum].pmti->EndCaretPos.y); } if(pCharRange->cpMin>pCharRange->cpMax){ long temp; temp=pCharRange->cpMin; pCharRange->cpMin=pCharRange->cpMax; pCharRange->cpMax=temp; } } void TextEdit_GetSelText(int WndNum,CHARRANGE *pCharRange,char *buffer){ extern MDIINFO MdiInfo[MAX_WNDNUM]; memcpy(buffer, MdiInfo[WndNum].pmti->buffer+pCharRange->cpMin, pCharRange->cpMax-pCharRange->cpMin); buffer[pCharRange->cpMax-pCharRange->cpMin]=0; } void GetScrollBaseCaretPos(int WndNum,int *pNaturalBaseX,int *pNaturalBaseY){ extern MDIINFO MdiInfo[MAX_WNDNUM]; HWND hEdit; hEdit=MdiInfo[WndNum].pmti->hEdit; //垂直スクロールバーの位置 SCROLLINFO si; si.cbSize=sizeof(SCROLLINFO); si.fMask=SIF_POS; GetScrollInfo(hEdit,SB_VERT,&si); *pNaturalBaseY-=si.nPos; //文字単位 //水平スクロールバーの位置 GetScrollInfo(hEdit,SB_HORZ,&si); *pNaturalBaseX-=si.nPos; //文字単位 } void GetNaturalBaseCaretPos(int WndNum,int *pScrollBaseX,int *pScrollBaseY){ extern MDIINFO MdiInfo[MAX_WNDNUM]; HWND hEdit; hEdit=GetWindow(MdiInfo[WndNum].hwnd,GW_CHILD); //垂直スクロールバーの位置 SCROLLINFO si; si.cbSize=sizeof(SCROLLINFO); si.fMask=SIF_POS; GetScrollInfo(hEdit,SB_VERT,&si); *pScrollBaseY+=si.nPos; //文字単位 //水平スクロールバーの位置 GetScrollInfo(hEdit,SB_HORZ,&si); *pScrollBaseX+=si.nPos; //文字単位 } void TextEdit_SetSel(int WndNum,int StartIndex,int EndIndex,BOOL bShowCenter){ extern MDIINFO MdiInfo[MAX_WNDNUM]; GetCaretPosFromBufferIndex( MdiInfo[WndNum].pmti->buffer, StartIndex, &MdiInfo[WndNum].pmti->StartCaretPos); GetCaretPosFromBufferIndex( MdiInfo[WndNum].pmti->buffer, EndIndex, &MdiInfo[WndNum].pmti->EndCaretPos); HWND hEdit; hEdit=GetWindow(MdiInfo[WndNum].hwnd,GW_CHILD); if(!TextEdit_ScrollCaret(WndNum,0,bShowCenter)) InvalidateRect(hEdit,NULL,0); ResetCaretPos(WndNum); ResetState_EditMenu(); } void TextEdit_SelectOneLine(int WndNum,int code_pos,BOOL bShowCenter){ extern MDIINFO MdiInfo[MAX_WNDNUM]; /////////////////////// // 定義行の選択範囲 /////////////////////// int iStartPos; iStartPos=code_pos; while(MdiInfo[WndNum].pmti->buffer[iStartPos]!='\n'&&iStartPos>0) iStartPos--; if(MdiInfo[WndNum].pmti->buffer[iStartPos]=='\n') iStartPos++; int iEndPos; iEndPos=code_pos; while(MdiInfo[WndNum].pmti->buffer[iEndPos]!='\r'&&MdiInfo[WndNum].pmti->buffer[iEndPos]!='\0') iEndPos++; TextEdit_SetSel(WndNum,iStartPos,iEndPos,bShowCenter); } void ResetCaretPos(int WndNum,BOOL bInputAndReset){ extern HANDLE hHeap; extern MDIINFO MdiInfo[MAX_WNDNUM]; int x,y; POINT OldPos; GetCaretPos(&OldPos); x=MdiInfo[WndNum].pmti->StartCaretPos.x; y=MdiInfo[WndNum].pmti->StartCaretPos.y; GetScrollBaseCaretPos(WndNum,&x,&y); //エディタ画面左端のコントロールタブ int iControlTabSpace; iControlTabSpace=MdiInfo[WndNum].pmti->iWidth_ControlTabSpace; //コントロールタブ上にカーソルがきたときに、非表示にする if(OldPos.x>=iControlTabSpace&&x<0) HideCaret(MdiInfo[WndNum].pmti->hEdit); else if(OldPos.x=0) ShowCaret(MdiInfo[WndNum].pmti->hEdit); SetCaretPos( x*font_width +iControlTabSpace, y*font_height); SetStatusText(NULL); ////////////////////////////////////////////// // Web検索文字列 ////////////////////////////////////////////// if(IS_DOCUMENT_TEXT(MdiInfo[WndNum].DocType)){ int start,end; if(MdiInfo[WndNum].pmti->StartCaretPos.x==MdiInfo[WndNum].pmti->EndCaretPos.x&& MdiInfo[WndNum].pmti->StartCaretPos.y==MdiInfo[WndNum].pmti->EndCaretPos.y){ //文字列を選択中でないとき int sw=0; if(bInputAndReset){ if(MdiInfo[WndNum].pmti->StartCaretPos.x>1){ MdiInfo[WndNum].pmti->StartCaretPos.x-=2; sw=1; } } TextEdit_GetWordCaret( MdiInfo[WndNum].pmti->hEdit, WndNum, &MdiInfo[WndNum].pmti->StartCaretPos, &start,&end, WORDCARET_BEFORE); if(sw) MdiInfo[WndNum].pmti->StartCaretPos.x+=2; //半角文字列を選択時の全角とのズレを修正 POINT pos; GetCaretPosFromBufferIndex(MdiInfo[WndNum].pmti->buffer,start,&pos); start=GetBufferIndexFromCaretPos(MdiInfo[WndNum].pmti->buffer,pos.x,pos.y); GetCaretPosFromBufferIndex(MdiInfo[WndNum].pmti->buffer,end,&pos); end=GetBufferIndexFromCaretPos(MdiInfo[WndNum].pmti->buffer,pos.x,pos.y); } else{ //文字列を選択中のとき start=GetBufferIndexFromCaretPos( MdiInfo[WndNum].pmti->buffer, MdiInfo[WndNum].pmti->StartCaretPos.x, MdiInfo[WndNum].pmti->StartCaretPos.y); end=GetBufferIndexFromCaretPos( MdiInfo[WndNum].pmti->buffer, MdiInfo[WndNum].pmti->EndCaretPos.x, MdiInfo[WndNum].pmti->EndCaretPos.y); } if(start>end){ int iTemp; iTemp=start; start=end; end=iTemp; } char *pTemp; int length; length=end-start; if(length<0) length=0; pTemp=(char *)HeapAlloc(hHeap,0,length+1024); memcpy(pTemp,MdiInfo[WndNum].pmti->buffer+start,length); pTemp[length]=0; char *temp2; temp2=strstr(pTemp,"\r\n"); if(temp2) temp2[0]=0; extern HWND hWebSearchCombo; SetWindowText(GetWindow(hWebSearchCombo,GW_CHILD),pTemp); //未完成 HeapDefaultFree(pTemp); /*if((!IsHiragana(pTemp))&&pTemp[0]&&pTemp[1]){ //バックグラウンドでWeb検索をかける _beginthread(WebSearchThread,0,(void *)pTemp); //※pTempはWebSearchThreadスレッド内で破棄する } else{ HeapDefaultFree(pTemp); }*/ } //////////////////////////////////////////////////// // パラメータヒントを更新 //////////////////////////////////////////////////// extern METHODCHECKINFO MethodCheckInfo; if(MethodCheckInfo.hWnd){ if(MdiInfo[WndNum].DocType==WNDTYPE_BASIC) ShowParameterHint(WndNum); } ////////////////////////////////// // コード補完機能を利用中の場合 ////////////////////////////////// extern COMPLEMENT_WINDOW_INFO ComplementWndInfo; if(ComplementWndInfo.hWnd){ int i,i2; char *pTemp,temporary[VN_SIZE]; i=GetBufferIndexFromCaretPos(MdiInfo[WndNum].pmti->buffer, MdiInfo[WndNum].pmti->StartCaretPos.x, MdiInfo[WndNum].pmti->StartCaretPos.y); if(ibuffer+ComplementWndInfo.iPos, ComplementWndInfo.iLength); pTemp[ComplementWndInfo.iLength]=0; for(i=0;iが消されたとき) // 補完ウィンドウを破棄する DestroyWindow(ComplementWndInfo.hWnd); ComplementWndInfo.hWnd=0; return; } pTemp=(char *)HeapAlloc(hHeap,0,ComplementWndInfo.iLength+1); memcpy(pTemp, MdiInfo[WndNum].pmti->buffer+ComplementWndInfo.iPos, ComplementWndInfo.iLength); pTemp[ComplementWndInfo.iLength]=0; for(i=0;ihEdit; x=MdiInfo[WndNum].pmti->StartCaretPos.x; y=MdiInfo[WndNum].pmti->StartCaretPos.y; GetScrollBaseCaretPos(WndNum,&x,&y); //垂直方向 SCROLLINFO si; si.cbSize=sizeof(SCROLLINFO); si.fMask=SIF_POS|SIF_PAGE|SIF_RANGE; GetScrollInfo(hEdit,SB_VERT,&si); if(bShowCenter==0){ //通常キャレットスクロール if(y<0){ //上へスクロール si.nPos+=y; SetScrollInfo(hEdit,SB_VERT,&si,1); InvalidateRect(hEdit,NULL,0); bScroll=1; } if(si.nPage&&y>(int)si.nPage-1){ //下へスクロール si.nPos+=y-si.nPage; SetScrollInfo(hEdit,SB_VERT,&si,1); InvalidateRect(hEdit,NULL,0); bScroll=1; } } else{ //上部にキャレットがくるようにスクロール if(y<0|| si.nPage&&y>(int)si.nPage-1){ si.nPos+=y-si.nPage/3; SetScrollInfo(hEdit,SB_VERT,&si,1); InvalidateRect(hEdit,NULL,0); bScroll=1; } } //水平方向 GetScrollInfo(hEdit,SB_HORZ,&si); if(x<0){ si.nPos+=x-1; if(!bScrollOneStep_x) si.nPos-=si.nPage/4; if(si.nPos<0) si.nPos=0; SetScrollInfo(hEdit,SB_HORZ,&si,1); InvalidateRect(hEdit,NULL,0); bScroll=1; } if(si.nPage&&x>(int)si.nPage){ si.nPos+=x-si.nPage; if(!bScrollOneStep_x) si.nPos+=si.nPage/3; SetScrollInfo(hEdit,SB_HORZ,&si,1); InvalidateRect(hEdit,NULL,0); bScroll=1; } return bScroll; } void CaretPos_LooseToNatural(int WndNum,int loose_x,int loose_y,POINT *pCaretPos){ extern MDIINFO MdiInfo[MAX_WNDNUM]; int i,i2,LastPos; int x,y; char *pBuf; //負数の場合は0をセット if(loose_x<0) loose_x=0; if(loose_y<0) loose_y=0; pBuf=MdiInfo[WndNum].pmti->buffer; // 行の確認 LastPos=0; for(i=0,x=0,y=0;;i++,x++){ if(y>=loose_y){ pCaretPos->y=y; break; } if(pBuf[i]=='\0'){ pCaretPos->y=y; i=LastPos; break; } if(IsRightTurn(pBuf,i,x)){ LastPos=i; //右端で折り返す y++; x=-1; i--; continue; } if(pBuf[i]=='\r'&&pBuf[i+1]=='\n'){ LastPos=i+2; y++; i++; x=-1; } if(pBuf[i]=='\t'){ //タブ文字 int tab; tab=pobj_nv->TabSize; if(x%tab==0) i2=tab; else i2=tab-x%tab; x+=i2-1; continue; } else if(IsDBCSLeadByte(pBuf[i])){ //マルチバイト文字 x++; i++; continue; } } //列の確認 x=0; for(;;i++,x++){ if(IsRightTurn(pBuf,i,x)){ //折り返しよりも右側が指定場所のとき pCaretPos->x=x; break; } if(pBuf[i]=='\t'){ //タブ文字 int tab; tab=pobj_nv->TabSize; if(x%tab==0) i2=tab; else i2=tab-x%tab; if(x+i2-1>=loose_x){ //指定場所にキャレットが存在するとき(タブ内) pCaretPos->x=x; break; } x+=i2-1; continue; } else if(IsDBCSLeadByte(pBuf[i])){ //マルチバイト文字 x++; i++; if(x>=loose_x){ //マルチバイト文字の間にキャレットが存在するとき pCaretPos->x=x-1; break; } continue; } if(x>=loose_x){ //指定場所にキャレットが存在するとき(通常) pCaretPos->x=x; break; } if(pBuf[i]=='\r'&&pBuf[i+1]=='\n'||pBuf[i]=='\0'){ //改行文字よりも右側が指定場所のとき pCaretPos->x=x; break; } } } void GetNaturalCaretPos_Click(int WndNum,int mouse_x,int mouse_y,POINT *pCaretPos){ ///////////////////////////// // キャレット移動(クリック) ///////////////////////////// extern MDIINFO MdiInfo[MAX_WNDNUM]; //ピクセル座標をカーソル座標(文字単位)に変更 mouse_x=(int)((double)mouse_x/(double)font_width+0.5); mouse_y/=font_height; GetNaturalBaseCaretPos(WndNum,&mouse_x,&mouse_y); CaretPos_LooseToNatural(WndNum,mouse_x,mouse_y,pCaretPos); } void GetNaturalCaretPos_Left(int WndNum){ /////////////////////////// // キャレット移動(左キー) /////////////////////////// extern MDIINFO MdiInfo[MAX_WNDNUM]; int i; int x,y; char *pBuf; POINT *pCaretPos; pCaretPos=&MdiInfo[WndNum].pmti->StartCaretPos; if(pCaretPos->x==0&&pCaretPos->y==0){ //ファイルの先頭から左へは行けない return; } pBuf=MdiInfo[WndNum].pmti->buffer; i=GetBufferIndexFromCaretPos(pBuf, pCaretPos->x, pCaretPos->y); if(i>=2){ if(pBuf[i-2]=='\r'&&pBuf[i-1]=='\n'){ //列先頭から前行の終端へ x=INT_MAX; y=pCaretPos->y-1; CaretPos_LooseToNatural(WndNum, x,y, pCaretPos); return; } } x=pCaretPos->x-1; y=pCaretPos->y; BOOL sw=0; if(x<0){ x=INT_MAX; y--; sw=1; } CaretPos_LooseToNatural(WndNum, x,y, pCaretPos); if(sw){ GetNaturalCaretPos_Left(WndNum); } } void GetNaturalCaretPos_Right(int WndNum,POINT *pCaretPos){ /////////////////////////// // キャレット移動(右キー) /////////////////////////// extern MDIINFO MdiInfo[MAX_WNDNUM]; int i,i2; char *pBuf; pBuf=MdiInfo[WndNum].pmti->buffer; i=GetBufferIndexFromCaretPos(pBuf, pCaretPos->x, pCaretPos->y); if(pBuf[i]=='\0'){ //ファイルの終端から右へは行けない return; } else if(pBuf[i]=='\r'&&pBuf[i+1]=='\n'){ //改行コードから右へ pCaretPos->x=0; pCaretPos->y++; } else if(pBuf[i]=='\t'){ //タブ文字から右へ int tab; tab=pobj_nv->TabSize; if(pCaretPos->x%tab==0) i2=tab; else i2=tab-pCaretPos->x%tab; pCaretPos->x+=i2; } else if(IsDBCSLeadByte(pBuf[i])){ //マルチバイト文字 pCaretPos->x+=2; } else{ //右へ(通常) pCaretPos->x++; } //折り返し int iMax_OneLine_TextLength; iMax_OneLine_TextLength=40; if(IsRightTurn(pBuf,i,pCaretPos->x)){ pCaretPos->x=0; pCaretPos->y++; } CaretPos_LooseToNatural(WndNum, pCaretPos->x, pCaretPos->y, pCaretPos); } void GetNaturalCaretPos_Up(int WndNum,POINT *pCaretPos){ /////////////////////////// // キャレット移動(上キー) /////////////////////////// extern MDIINFO MdiInfo[MAX_WNDNUM]; if(pCaretPos->y==0){ //1行目にキャレットがあるとき return; } //上下のキャレット移動時には、左右方向の位置を保持する if(MdiInfo[WndNum].pmti->Temp_UpDown_CaretXPos==-1) MdiInfo[WndNum].pmti->Temp_UpDown_CaretXPos=pCaretPos->x; pCaretPos->y--; CaretPos_LooseToNatural(WndNum, MdiInfo[WndNum].pmti->Temp_UpDown_CaretXPos, pCaretPos->y, pCaretPos); } void GetNaturalCaretPos_Down(int WndNum,POINT *pCaretPos){ /////////////////////////// // キャレット移動(下キー) /////////////////////////// extern MDIINFO MdiInfo[MAX_WNDNUM]; //上下のキャレット移動時には、左右方向の位置を保持する if(MdiInfo[WndNum].pmti->Temp_UpDown_CaretXPos==-1) MdiInfo[WndNum].pmti->Temp_UpDown_CaretXPos=pCaretPos->x; pCaretPos->y++; CaretPos_LooseToNatural(WndNum, MdiInfo[WndNum].pmti->Temp_UpDown_CaretXPos, pCaretPos->y, pCaretPos); } void GetNaturalCaretPos_PageUp(int WndNum,POINT *pCaretPos){ /////////////////////////////// // キャレット移動(PageUpキー) /////////////////////////////// extern MDIINFO MdiInfo[MAX_WNDNUM]; if(pCaretPos->y==0){ //1行目にキャレットがあるとき return; } //上下のキャレット移動時には、左右方向の位置を保持する if(MdiInfo[WndNum].pmti->Temp_UpDown_CaretXPos==-1) MdiInfo[WndNum].pmti->Temp_UpDown_CaretXPos=pCaretPos->x; SCROLLINFO si; si.cbSize=sizeof(SCROLLINFO); si.fMask=SIF_PAGE; GetScrollInfo(MdiInfo[WndNum].pmti->hEdit,SB_VERT,&si); pCaretPos->y-=si.nPage; if(pCaretPos->y<0) pCaretPos->y=0; CaretPos_LooseToNatural(WndNum, MdiInfo[WndNum].pmti->Temp_UpDown_CaretXPos, pCaretPos->y, pCaretPos); } void GetNaturalCaretPos_PageDown(int WndNum,POINT *pCaretPos){ /////////////////////////////// // キャレット移動(PageUpキー) /////////////////////////////// extern MDIINFO MdiInfo[MAX_WNDNUM]; //上下のキャレット移動時には、左右方向の位置を保持する if(MdiInfo[WndNum].pmti->Temp_UpDown_CaretXPos==-1) MdiInfo[WndNum].pmti->Temp_UpDown_CaretXPos=pCaretPos->x; SCROLLINFO si; si.cbSize=sizeof(SCROLLINFO); si.fMask=SIF_PAGE; GetScrollInfo(MdiInfo[WndNum].pmti->hEdit,SB_VERT,&si); pCaretPos->y+=si.nPage; CaretPos_LooseToNatural(WndNum, MdiInfo[WndNum].pmti->Temp_UpDown_CaretXPos, pCaretPos->y, pCaretPos); }