#include "myWin.h" #define GRD_ED1 1001 // エディット番号 #define GRD_LB1 2001 // ラベル番号 #define GRD_BT1 3002 // プッシュボタン番号(OK) #define GRD_BT2 3003 // プッシュボタン番号(Cancel) #define GRD_BRD 3004 // プッシュボタン番号(行削除) #define GRD_BRI 3005 // プッシュボタン番号(行挿入) #define GRD_BRN 3006 // プッシュボタン番号(行番号) #define GRD_BCD 3007 // プッシュボタン番号(列削除) #define GRD_BCI 3008 // プッシュボタン番号(列挿入) #define GRD_BCN 3009 // プッシュボタン番号(列番号) #define GRD_HSC 4001 // 水平スクロール番号 #define GRD_VSC 4002 // 垂直スクロール番号 #define GRD_MAXCOL 60 // 最大桁数 #define GRD_MAXROW 30 // 最大行数 #define GRD_MAXSTR 100 // セル文字最大数 #define GRD_SELECT_REGION 0 // 範囲選択 #define GRD_SELECT_ROW 1 // 行選択 #define GRD_SELECT_COL 2 // 桁選択 #define GRD_SELECT_ALL 3 // 全選択 #define swap(type, X, Y) do{type T; T=X; X=Y; Y=T;} while(0) typedef struct{//■列見出しデータ UINT align, valign; //列見出しの水平表示位置と垂直表示位置(DrawTextのdwDTFormatの値) int bkcolor, color, width; //背景色、文字色、列の幅 HFONT hf; //論理フォントのハンドル(CreateFont関数を参照) TCHAR text[GRD_MAXSTR+1]; //列見出しの文字列 }colData; typedef struct{//■列見出しデータコレクション int count, height; //列見出しの数と高さ colData header[GRD_MAXCOL]; //列見出しのデータ(個数はcountで指定) }colDataSet; typedef struct{//■行見出しデータ UINT align, valign; //行見出しの水平表示位置と垂直表示位置(DrawTextのdwDTFormatの値) int bkcolor, color, height; //背景色、文字色、行の高さ HFONT hf; //論理フォントのハンドル(CreateFont関数を参照) TCHAR text[GRD_MAXSTR+1]; //行見出しの文字列 }rowData; typedef struct{//■行見出しデータコレクション int count, width; //行見出しの数と幅 rowData header[GRD_MAXROW]; //行見出しのデータ(個数はcountで指定) }rowDataSet; typedef struct{//■セルデータ UINT align, valign; //セルの水平表示位置と垂直表示位置(DrawTextのdwDTFormatの値) int bkcolor, color; //背景色、文字色(行の高さは行見出データ、列の高さは列見出しデータ) HFONT hf; //論理フォントのハンドル(CreateFont関数を参照) TCHAR text[GRD_MAXSTR+1]; //セルの文字列 }cellData; typedef struct{//■セル位置データ int col, row; //列位置(col)と行位置(raw) }cellPoint; typedef struct{//■グリッドデータ(セルの2次元配列) int width, height; //グリッド表示大きさ(見出しを含んだ全体の幅と高さ) cellPoint dStart, dEnd; //表示中の左上隅と右下隅のセル位置 cellPoint active; //アクティブセルの位置 cellPoint selectEnd; //選択位置の終了(activeとselectEndで示される矩形状の領域が選択範囲) colDataSet col; //列見出しデータ rowDataSet row; //行見出しデータ cellData cell[GRD_MAXROW][GRD_MAXCOL];//セルデータ(二次元) HWND label, edit, btOK,btCancel,hScroll, vScroll; HWND btRDel, btRIns, btRNo, btCDel, btCIns, btCNo; SCROLLINFO hSInfo, vSInfo; int selectMode; }gridData; //■領域宣言---------------------------------------- static gridData grid; //グリッドデータ static gridData copyGrid; //セル範囲のCopy&Paste用 static HFONT hfheader,hfdata; //フォントデータ(見出し用とデータ用) static HDC hBuff; static HBITMAP hBM; // ビットマップ表示用 static int editMode=false; //テキスト編集モードかどうかのフラグ static int dragMode=false; static int copyRangeEmpty=true; //Paste可能データが空のときtrue static int lButtonDown=false; WNDPROC stStaticProc; static HWND rc;static TCHAR str[256]; WNDPROC stEditProc; void clearBitmap(){ SelectObject(hBuff,GetStockObject(NULL_PEN)); PatBlt(hBuff,0,0,grid.width,grid.height,WHITENESS); } //■選択範囲設定、取り出しの共通関数---------------------------------------- void setSelectEnd(gridData *grid, int col, int row){//setSelect(&grid, col, row) (*grid).selectMode=GRD_SELECT_REGION; (*grid).selectEnd.col=col; (*grid).selectEnd.row=row; } void setSelectEnd(gridData *grid, cellPoint cell){//setSelect(&grid, col, row) (*grid).selectMode=GRD_SELECT_REGION; (*grid).selectEnd.col=cell.col; (*grid).selectEnd.row=cell.row; } void getSelectEnd(gridData grid, int *getCol, int *getRow){//setSelect(&grid, col, row) if(grid.selectEnd.col>=0) *getCol=grid.selectEnd.col; else *getCol=grid.active.col; if(grid.selectEnd.row>=0) *getRow=grid.selectEnd.row; else *getRow=grid.active.row; } void getSelectEnd(gridData grid, cellPoint *cell){//setSelect(&grid, col, row) if(grid.selectEnd.col>=0)(*cell).col=grid.selectEnd.col;else (*cell).col=grid.active.col; if(grid.selectEnd.row>=0)(*cell).row=grid.selectEnd.row;else (*cell).row=grid.active.row; } int getSelectRow(gridData grid){ if(grid.selectEnd.row>=0)return grid.selectEnd.row; else return grid.active.row; } int getSelectCol(gridData grid){ if(grid.selectEnd.col>=0)return grid.selectEnd.col; else return grid.active.col; } void setActiveCell(gridData *grid, int col, int row){//setSelect(&grid, col, row) (*grid).selectMode=GRD_SELECT_REGION; (*grid).active.col=col; (*grid).active.row=row; } void setActiveCell(gridData *grid, cellPoint cell){//setSelect(&grid, col, row) (*grid).selectMode=GRD_SELECT_REGION; (*grid).active.col=cell.col; (*grid).active.row=cell.row; } void getActiveCell(gridData grid, int *col, int *row){//setSelect(&grid, col, row) *col=grid.active.col; *row=grid.active.row; } void getActiveCell(gridData grid, cellPoint *cell){//setSelect(&grid, col, row) (*cell).col=grid.active.col; (*cell).row=grid.active.row; } //■グリッドの生成---------------------------------------- void gridCreate(gridData *grid, int numCol, int numRow){ hfheader=CreateFont(16,0,0,0, FW_BOLD, FALSE, FALSE,FALSE, //見出し用フォント(標準) SHIFTJIS_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FIXED_PITCH|FF_MODERN,NULL); hfdata=CreateFont(16,0,0,0, FW_NORMAL, FALSE, FALSE,FALSE, //データ用フォント(標準) SHIFTJIS_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FIXED_PITCH|FF_MODERN,NULL); //グリッドデータの標準値初期設定 (*grid).width = 550; (*grid).height = 230; //表示サイズ (*grid).dStart.col = 0; (*grid).dStart.row = 0; //左上隅 (*grid).dEnd.col = 9; (*grid).dEnd.row = 9; //右下隅 (*grid).col.count = numCol; (*grid).row.count = numRow; (*grid).col.height = 20; //グリッドデータの標準値初期設定 (*grid).row.width = 50; //桁属性 for(int i=0; igrid.height){grid.dEnd.row=i-1; break;} if(i>=ist){ for(int j=grid.dStart.col;j<=jed;j++){ X1=X2; X2+=grid.col.header[j].width; if(X2>grid.width){grid.dEnd.col=j-1; break;} if(j>=jst) Rectangle(hBuff, X1,Y1,X2,Y2); } } } SetROP2(hBuff, R2_COPYPEN);//ラスタオペレーションを既定値に戻す DeleteObject(hbrush);DeleteObject(hpen); } void colHeader(int X1,int Y1, int X2,int Y2,TCHAR text[], int color, //■colヘッダー表示 int bkcolor, HFONT hf, UINT align, UINT valign){ drawHeaderFig(X1,Y1, X2,Y2, bkcolor); SelectObject(hBuff,hf); drawText(text,X1,Y1,X2,Y2, color, align | valign); } void rowHeader(int X1,int Y1, int X2,int Y2,TCHAR text[], int color, //■rowヘッダー表示 int bkcolor, HFONT hf, UINT align, UINT valign){ drawHeaderFig(X1,Y1, X2,Y2, bkcolor); SelectObject(hBuff,hf); drawText(text,X1,Y1,X2,Y2, color,align|valign); } void dspData(int X1,int Y1, int X2,int Y2,TCHAR text[], int color, //■データ表示 int bkcolor, HFONT hf, UINT align, UINT valign){ drawDataFig(X1,Y1, X2,Y2, bkcolor); SelectObject(hBuff, hf); drawText(text,X1,Y1,X2,Y2, color, align|valign); } void drawGrid(HWND hw, gridData grid){ //■グリッド全体表示 clearBitmap(); int numRow=grid.row.count, numCol=grid.col.count; int colH=grid.col.height, rowW=grid.row.width; int X1=0,Y1=0, X2=X1+rowW, Y2=Y1+colH; drawHeaderFig(X1,Y1, X2,Y2, 0xCCCCCC);//見出し形状表示 for(int i=grid.dStart.col;igrid.width){grid.dEnd.col=i-1; break;} colHeader(X1,Y1,X2,Y2, grid.col.header[i].text, grid.col.header[i].color, grid.col.header[i].bkcolor, grid.col.header[i].hf, grid.col.header[i].align,grid. col.header[i].valign); } for(int i=grid.dStart.row;igrid.height){grid.dEnd.row=i-1; break;} rowHeader(X1,Y1,X2,Y2,grid.row.header[i].text, grid.row.header[i].color, grid.row.header[i].bkcolor, grid.row.header[i].hf, grid.row.header[i].align, grid.row.header[i].valign); for(int j=grid.dStart.col;jgrid.width){grid.dEnd.col=i-1; break;} dspData(X1,Y1, X2,Y2,grid.cell[i][j].text, grid.cell[i][j].color, grid.cell[i][j].bkcolor,grid.cell[i][j].hf, grid.cell[i][j].align, grid.cell[i][j].valign); if(grid.active.col==j && grid.active.row==i) drawCursor(X1,Y1,X2,Y2);//Active表示 } } int i,j,kc,kr; getActiveCell(grid, &j,&i);//選択範囲表示 getSelectEnd(grid, &kc, &kr); if(kc>=0 && kr>=0 && (kc !=j || kr !=i)){ int jst=min(j,kc), jed=max(j,kc), ist=min(i,kr), ied=max(i, kr); drawSelect(ist, ied, jst, jed); } InvalidateRect(hw,NULL,TRUE); } void checkGrid(HWND hw, gridData *grid){//■表示範囲のチェック(表示範囲の設定) int numRow=(*grid).row.count, numCol=(*grid).col.count; int colH=(*grid).col.height, rowW=(*grid).row.width; int ist=(*grid).dStart.row, jst=(*grid).dStart.col; int X1=0,Y1=0, X2=X1+rowW, Y2=Y1+colH; (*grid).dEnd.row=numRow-1; for(int i=ist;i(*grid).height){(*grid).dEnd.row=i-1; break;} } (*grid).dEnd.col=numCol-1; for(int j=jst;j(*grid).width){(*grid).dEnd.col=j-1; break;} } } void drawRectangle(int X1, int Y1, int X2, int Y2, int borderColor, int paintColor){//■矩形表示共通関数 HPEN hpen = CreatePen(PS_SOLID,1,borderColor); SelectObject(hBuff,hpen ); HBRUSH hbrush = CreateSolidBrush(paintColor) ; SelectObject(hBuff,hbrush); Rectangle(hBuff,X1,Y1, X2,Y2); DeleteObject(hbrush);DeleteObject(hpen); } //■開始時の初期設定---------------------------------------------------------------- void setColText(gridData *grid,int colNo, TCHAR text[]){//■列見出し文字列の設定 lstrcpy((*grid).col.header[colNo].text, text); } void setRowText(gridData *grid,int rowNo, TCHAR text[]){//■行見出し文字列の設定 lstrcpy((*grid).row.header[rowNo].text, text); } void setCellText(gridData *grid,int rowNo, int colNo, TCHAR text[]){//■データ文字列設定 lstrcpy((*grid).cell[rowNo][colNo].text, text); } void stProcPaint(HWND hw, WPARAM wp, LPARAM lp){//■ビットマップを画面に表示 PAINTSTRUCT ps; HDC hdc=BeginPaint(hw, &ps); BitBlt(hdc, 0,0, 700,700,hBuff,0,0,SRCCOPY); EndPaint(hw,&ps); } void createLabel(HWND *lbl, HWND hw, LPARAM lp, HMENU hm, int X, int Y,TCHAR *str){//■ラベル生成 *lbl=CreateWindow(TEXT("STATIC"),str, WS_CHILD|WS_VISIBLE|SS_RIGHT, X,Y,70,20,hw,hm, hInstance, NULL); } void moveAndSetText(int col, int row){//■セルデータを設定してセル移動モードにする SetWindowText(grid.edit, grid.cell[row][col].text); editMode=false; SetFocus(rc); } void edReturn(HWND hw){//■確定処理(OKボタンが押されたとき) int col=grid.active.col, row=grid.active.row, mx=grid.row.count-1; GetWindowText(grid.edit,grid.cell[row][col].text,GRD_MAXSTR); if(row0) { (*grid).selectEnd.col=--col; if(col<(*grid).dStart.col){ (*grid).dStart.col=col;checkGrid(hw, grid); drawGrid(hw,*grid); } } } void moveCursorRight(HWND hw, gridData *grid){//■セル右移動 int col=(*grid).selectEnd.col, max=(*grid).col.count-1; if(col(*grid).dEnd.col && i<=col; i++){ (*grid).dStart.col=i;checkGrid(hw, grid); } if(ist!=(*grid).dStart.col) drawGrid(hw,*grid); } } void moveCursorUp(HWND hw, gridData *grid){//■セル上移動 int row=(*grid).selectEnd.row; if(row>0){ (*grid).selectEnd.row=--row; if(row<(*grid).dStart.row){ (*grid).dStart.row=row;checkGrid(hw, grid); drawGrid(hw,*grid); } } } void moveCursorDown(HWND hw, gridData *grid){//■セル下移動 int row=(*grid).selectEnd.row, max=(*grid).row.count-1; if(row(*grid).dEnd.row && i<=row; i++){ (*grid).dStart.row=i;checkGrid(hw, grid); } if(ist!=(*grid).dStart.row) drawGrid(hw,*grid); } } //■選択セル判定 ---------------------------------------- int colNo(int X, gridData g){//■列位置判定 int numCol=grid.col.count, X1=0,X2=X1+g.row.width; for(int i=g.dStart.col;i<=g.dEnd.col;i++){ X1=X2; X2+=g.col.header[i].width; if(X>=X1 && X<=X2) return i; } return -1; } int rowNo(int Y, gridData g){//■行位置判定 int numCol=grid.col.count, Y1=0,Y2=Y1+g.col.height; for(int i=g.dStart.row;i<=g.dEnd.row;i++){ Y1=Y2; Y2+=g.row.header[i].height; if(Y>=Y1 && Y<=Y2) return i; } return -1; } void coToCellNo(int X, int Y, gridData g, int *ip, int *jp){//■行・列位置判定 *ip=-1; *jp=-1; int numRow=g.row.count, numCol=grid.col.count; int colH=g.col.height, rowW=g.row.width; int X1=0,Y1=0, X2=X1+rowW, Y2=Y1+colH; int i=-1, j=-1; for(i=g.dStart.col;i<=g.dEnd.col;i++){ X1=X2; X2+=g.col.header[i].width; if(X>=X1 && X<=X2) break; } if(i<0) return; for(j=g.dStart.row;j<=g.dEnd.row;j++){ Y1=Y2; Y2+=g.row.header[i].height; if(Y>=Y1 && Y<=Y2)break; } if(j<0)return; *ip=i; *jp=j; } //■セル選択時のCopy/Paste--------------------------------------------------------- void moveData(cellData *dst, cellData src){//■データ複写 (*dst).align = src.align; (*dst).bkcolor = src.bkcolor; (*dst).color = src.color; (*dst).hf = src.hf; (*dst).valign = src.valign; lstrcpy((*dst).text, src.text); } void moveCol(colData *dst, colData src){//■列複写 (*dst).align = src.align; (*dst).bkcolor = src.bkcolor; (*dst).color = src.color; (*dst).width = src.width; (*dst).hf = src.hf; (*dst).valign = src.valign; lstrcpy((*dst).text, src.text); } void moveRow(rowData *dst, rowData src){//■行複写 (*dst).align = src.align; (*dst).bkcolor = src.bkcolor; (*dst).color = src.color; (*dst).height = src.height; (*dst).hf = src.hf; (*dst).valign = src.valign; lstrcpy((*dst).text, src.text); } void copyRange(){//■範囲の複写 int j, i, ii,jj,kc, kr; getActiveCell(grid, &j, &i); getSelectEnd(grid, &kc, &kr); if(kc<0) kc = j; if(kr<0) kr = i; int jst=min(kc,j), jed=max(kc,j), ist=min(kr,i), ied=max(kr,i); gridCreate(©Grid, jed-jst+1, ied-ist+1); copyGrid.row.width = grid.row.width ;copyGrid.col.height = grid.col.height; for(i=ist, ii=0;i<=ied; i++,ii++) moveRow(&(copyGrid.row.header[ii]),grid.row.header[i]); for(j=jst, jj=0;j<=jed; j++,jj++) moveCol(&(copyGrid.col.header[ii]),grid.col.header[i]); for(i=ist, ii=0;i<=ied; i++,ii++) for(j=jst, jj=0;j<=jed; j++,jj++) moveData(&(copyGrid.cell[ii][jj]), grid.cell[i][j]); copyRangeEmpty=false; } void pasteRange(HWND hw){//■範囲の貼付け if(copyRangeEmpty) return; int i, j,ii,jj, kc,kr; getActiveCell(grid, &j, &i);getSelectEnd(grid, &kc, &kr); if(kc<0) kc = j; if(kr<0) kr = i; int jst=min(kc,j), jed=max(kc,j), ist=min(kr,i), ied=max(kr,i); if(jst==jed && jst==jed){ ied = ist + copyGrid.row.count-1; jed = jst + copyGrid.col.count-1; } for(i=ist, ii=0;i<=ied && ii< copyGrid.row.count; i++,ii++) for(j=jst, jj=0;j<=jed && jj(GRD_MAXROW-1)){ wsprintf(str,TEXT("行数は最大 %d です。") TEXT("%d 行を挿入できないので挿入を中止します。"),GRD_MAXROW,n); MessageBox(hw,str,TEXT("制限エラー"),MB_OK); return; } for(int i=ned+n,j = ned;j>=ist;i--, j--){//n行後方に移動 moveRow(&(grid.row.header[i]), grid.row.header[j]); for(int k=0;k(GRD_MAXCOL-1)){ wsprintf(str,TEXT("列数は最大 %d です。") TEXT("%d 列を挿入できないので挿入を中止します。"),GRD_MAXCOL,n); MessageBox(hw,str,TEXT("制限エラー"),MB_OK); return; } for(int i=ned+n,j = ned;j>=ist;i--, j--){//n列後方に移動 moveCol(&(grid.col.header[i]), grid.col.header[j]); for(int k=0;k0; i++,DD /= 27 ) str[i]=(DD % 27)-1+CHAR('A'); N=i; str[N]=0; for(i=0,j=N-1; i=0 && j>=0)setSelectEnd(&grid, i,j); } } editMode=dragMode=false; drawGrid(hw, grid); } void stProcMouseMove(HWND hw, WPARAM wp, LPARAM lp){//■左ボタン移動 if(grid.selectMode==GRD_SELECT_ALL) return;//全体選択のときドラッギング無視 POINT p;p.x=LOWORD(lp), p.y=HIWORD(lp);ScreenToClient(hw,&p); int r; if(grid.selectMode==GRD_SELECT_ROW) {//行選択直後のドラッギングのとき行方向だけを判定 if((r=rowNo(p.y, grid))>=0) grid.selectEnd.row=r; } if(grid.selectMode==GRD_SELECT_COL) {//列方向直後のドラッギングのとき桁方向だけを判定 if((r=colNo(p.x, grid))>=0) grid.selectEnd.col=r; } else{//範囲指定のとき行・列の両方向を判定 int i,j; coToCellNo(p.x,p.y,grid, &i, &j); if(i>=0 && j>=0) setSelectEnd(&grid, i,j);//範囲外は無視 } drawGrid(hw, grid); } //■イベント判別関連--------------------------------------------------------- void eqCursor(HWND hw){//■シフトキーが押されていないときのカーソル移動のときの後処理 int col, row; getSelectEnd(grid, &col, &row); setActiveCell(&grid, col, row); SetWindowText(grid.edit,grid.cell[row][col].text); grid.selectMode=GRD_SELECT_REGION; drawGrid(hw, grid); } void stProcKeyDown(HWND hw, WPARAM wp, LPARAM lp){//■キーイベント判別 if(wp==VK_CONTROL)return; if(GetKeyState(VK_CONTROL)<0){//コントロールキーが押されているかどうかの判別 switch(wp){ case TCHAR('C'):copyRange() ; return;//[CTRL]+Cで複写 case TCHAR('V'):pasteRange(hw);return; //[CTRL]+Vで貼付け } } if(wp==VK_SHIFT)return; if(GetKeyState(VK_SHIFT)<0){//シフトキーが押されているかどうかの判別 switch(wp){//[SHIFT]+カーソルキーで範囲指定 case VK_LEFT : moveCursorLeft (hw, &grid);drawGrid(hw, grid); return; case VK_RIGHT : moveCursorRight(hw, &grid);drawGrid(hw, grid); return; case VK_UP : moveCursorUp (hw, &grid);drawGrid(hw, grid); return; case VK_DOWN : moveCursorDown (hw, &grid);drawGrid(hw, grid);return; } } switch(wp){//シフトキーが押されていないときのカーソルキーは選択移動 case VK_LEFT : moveCursorLeft (hw, &grid); eqCursor(hw);return; case VK_RIGHT : moveCursorRight(hw, &grid); eqCursor(hw);return; case VK_UP : moveCursorUp (hw, &grid); eqCursor(hw);return; case VK_DELETE : cellDelete (hw); return; case VK_BACK : cellDelete (hw); return; case VK_DOWN : case VK_RETURN : moveCursorDown (hw, &grid);eqCursor(hw);return; } } void stProcChar(HWND hw, WPARAM wp, LPARAM lp){//■文字がキーインされたときの処理 int cd=wp & 0xFF00; if(cd !=0 || (wp>=0x20 && wp!=0x7F)){//ASCIIの制御文字を無視する GetWindowText(grid.edit,str,GRD_MAXSTR); int n=lstrlen(str);//入力された文字をエディットボックスの文字列の最後に付加 if(n0) grid.hSInfo.nPos--; break; case SB_LINERIGHT: if(grid.hSInfo.nPos=(int)grid.hSInfo.nPage) grid.hSInfo.nPos-=grid.hSInfo.nPage ; break; case SB_PAGERIGHT:if((grid.hSInfo.nPos+(int)grid.hSInfo.nPage)>=grid.hSInfo.nMax-1) grid.hSInfo.nPos+=grid.hSInfo.nPage ; break; case SB_THUMBPOSITION: grid.hSInfo.nPos=HIWORD(wp); } SetScrollInfo(grid.hScroll,SB_CTL,&grid.hSInfo, TRUE); grid.dStart.col=grid.hSInfo.nPos; checkGrid(hw, &grid); drawGrid(hw, grid); //表示範囲の再設定 } void procVScroll(HWND hw, WPARAM wp,LPARAM lp){//■垂直スクロール処理 switch(LOWORD(wp)){ case SB_TOP : grid.vSInfo.nPos=grid.vSInfo.nMin ; break; case SB_BOTTOM : grid.vSInfo.nPos=grid.vSInfo.nMax ; break; case SB_LINEUP : if(grid.vSInfo.nPos>0) grid.vSInfo.nPos--; break; case SB_LINEDOWN: if(grid.vSInfo.nPos=(int)grid.vSInfo.nPage) grid.vSInfo.nPos-=grid.vSInfo.nPage ; break; case SB_PAGEDOWN:if((grid.vSInfo.nPos+(int)grid.vSInfo.nPage)>=grid.vSInfo.nMax-1) grid.vSInfo.nPos+=grid.vSInfo.nPage ; break; case SB_THUMBPOSITION: grid.vSInfo.nPos=HIWORD(wp); } SetScrollInfo(grid.vScroll,SB_CTL,&grid.vSInfo, TRUE); grid.dStart.row=grid.vSInfo.nPos; checkGrid(hw, &grid); drawGrid(hw, grid);//表示範囲の再設定 } LRESULT CALLBACK WndProc(HWND hw, UINT msg, WPARAM wp,LPARAM lp){//■メッセージ判定 switch(msg){ case WM_DESTROY : PostQuitMessage(0) ; return 0; case WM_KEYDOWN : SendMessage(rc,msg,wp,lp); return 0;//キー関連メッセージがスタティックに送られ case WM_CHAR : SendMessage(rc,msg,wp,lp); return 0;//ないので、これらをスタティックに送る。 case WM_COMMAND : procCommand(hw,wp,lp) ; return 0; case WM_HSCROLL : procHScroll(hw,wp,lp) ; return 0; case WM_VSCROLL : procVScroll(hw,wp,lp) ; return 0; case WM_SETFOCUS: return 0; case WM_CREATE : procCreate (hw,wp,lp) ; return 0; } return DefWindowProc(hw,msg,wp,lp); }