#include "stdafx.h" #include "Common.h" RGBQUAD DefaultColorTable16[16]={ 0,0,0,0, 0,0,128,0, 0,128,0,0, 0,128,128,0, 128,0,0,0, 128,0,128,0, 128,128,0,0, 128,128,128,0, 192,192,192,0, 0,0,255,0, 0,255,0,0, 0,255,255,0, 255,0,0,0, 255,0,255,0, 255,255,0,0, 255,255,255,0, }; RGBQUAD DefaultColorTable256[256]; //ファイルから読み込む(SetupProjectEditor関数を参照) void ResizeIconWindow(HWND hMain,HWND hToolDlg,HWND hColorDlg,int width,int height){ MoveWindow(hMain,0,0,width-170,height-50,1); MoveWindow(hToolDlg,width-170,0,170,height,1); MoveWindow(hColorDlg,0,height-50,width-170,50,1); } void ResetIconType(int WndNum){ extern MDIINFO MdiInfo[MAX_WNDNUM]; int i; HWND hCombo; char temporary[MAX_PATH]; BITMAPINFOHEADER *pBmpInfoHdr; hCombo=GetDlgItem(MdiInfo[WndNum].MdiIconEditInfo->hToolDlg,IDC_ICONTYPECOMBO); for(i=0;inum;i++){ pBmpInfoHdr=(BITMAPINFOHEADER *)MdiInfo[WndNum].MdiIconEditInfo->pIconImage[i]; //例: "32*32 (xxxx色)" sprintf(temporary,"%d*%d (%d%s)", pBmpInfoHdr->biWidth, pBmpInfoHdr->biHeight/2, (int)pow((double)2,(double)pBmpInfoHdr->biBitCount), STRING_UNIT_COLORS); SendMessage(hCombo,CB_ADDSTRING,0,(long)temporary); } SendMessage(hCombo,CB_SETCURSEL,0,0); } BYTE *CreateIconType(int IconType,DWORD *dwBytes){ extern HANDLE hHeap; int i,width,BitCount,dwBytesInRes; BITMAPINFOHEADER *pBmpHdr; BYTE *pImageBuffer; switch(IconType){ case ICONTYPE_16_16: width=16; BitCount=4; break; case ICONTYPE_16_256: width=16; BitCount=8; break; case ICONTYPE_32_16: width=32; BitCount=4; break; case ICONTYPE_32_256: width=32; BitCount=8; break; } //イメージサイズを計算 dwBytesInRes=sizeof(BITMAPINFOHEADER)+ sizeof(RGBQUAD)*(int)pow((double)2,(double)BitCount)+ BitCount*width*width/8; if(width==16) dwBytesInRes+=width*width*2/8; else dwBytesInRes+=width*width/8; *dwBytes=dwBytesInRes; //メモリ領域を確保 pImageBuffer=(BYTE *)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,dwBytesInRes); //ヘッダ情報をセット pBmpHdr=(BITMAPINFOHEADER *)pImageBuffer; pBmpHdr->biSize=sizeof(BITMAPINFOHEADER); pBmpHdr->biWidth=width; pBmpHdr->biHeight=width*2; pBmpHdr->biPlanes=1; pBmpHdr->biBitCount=BitCount; //カラーテーブルをセット RGBQUAD *pRgbq; pRgbq=(RGBQUAD *)(pImageBuffer+sizeof(BITMAPINFOHEADER)); if(BitCount==4){ //16色 memcpy(pRgbq,DefaultColorTable16,sizeof(RGBQUAD)*16); } else if(BitCount==8){ //256色 memcpy(pRgbq,DefaultColorTable256,sizeof(RGBQUAD)*256); } //マスクビットをセット BYTE *pMaskBuf; pMaskBuf=pImageBuffer+ sizeof(BITMAPINFOHEADER)+ sizeof(RGBQUAD)*(int)pow((double)2,(double)BitCount)+ BitCount*width*width/8; if(width==16){ //一行の4バイト境界を考慮 for(i=0;i<16;i++){ pMaskBuf[i*4]=0xFF; pMaskBuf[i*4+1]=0xFF; pMaskBuf[i*4+2]=0; pMaskBuf[i*4+3]=0; } } else memset(pMaskBuf,0xFF,width*width/8); return pImageBuffer; } void AddIconType(int WndNum,int IconType){ extern HANDLE hHeap; extern MDIINFO MdiInfo[MAX_WNDNUM]; int i,width,BitCount; switch(IconType){ case ICONTYPE_16_16: width=16; BitCount=4; break; case ICONTYPE_16_256: width=16; BitCount=8; break; case ICONTYPE_32_16: width=32; BitCount=4; break; case ICONTYPE_32_256: width=32; BitCount=8; break; } MdiInfo[WndNum].MdiIconEditInfo->pIconImage[MdiInfo[WndNum].MdiIconEditInfo->num]= CreateIconType(IconType, &MdiInfo[WndNum].MdiIconEditInfo->dwBytesInRes[MdiInfo[WndNum].MdiIconEditInfo->num]); //イメージ選択用のメモリを解放 if(MdiInfo[WndNum].MdiIconEditInfo->SelectLevel==2) DeleteObject(MdiInfo[WndNum].MdiIconEditInfo->hSelectingBmp); MdiInfo[WndNum].MdiIconEditInfo->SelectLevel=0; //アイコンタイプを追加 MdiInfo[WndNum].MdiIconEditInfo->SelectIconNum=MdiInfo[WndNum].MdiIconEditInfo->num; MdiInfo[WndNum].MdiIconEditInfo->num++; //変更情報を初期化 i=MdiInfo[WndNum].MdiIconEditInfo->SelectIconNum; MdiInfo[WndNum].MdiIconEditInfo->undo[i].NowPos=0; memset(MdiInfo[WndNum].MdiIconEditInfo->undo[i].lpData,0,sizeof(BYTE *)*MAX_ICONEDIT_UNDONUM); //アイコンタイプコンボボックスに追加 char temporary[32]; HWND hCombo; hCombo=GetDlgItem(MdiInfo[WndNum].MdiIconEditInfo->hToolDlg,IDC_ICONTYPECOMBO); //例: "32*32 (xxxx色)" sprintf(temporary,"%d*%d (%d%s)", width, width, (int)pow((double)2,(double)BitCount), STRING_UNIT_COLORS); i=SendMessage(hCombo,CB_ADDSTRING,0,(long)temporary); SendMessage(hCombo,CB_SETCURSEL,i,0); //再描画 HBRUSH hOldBrush; hOldBrush=(HBRUSH)SelectObject(MdiInfo[WndNum].MdiIconEditInfo->memdc,GetStockObject(WHITE_BRUSH)); PatBlt(MdiInfo[WndNum].MdiIconEditInfo->memdc,0,0,400,400,PATCOPY); SelectObject(MdiInfo[WndNum].MdiIconEditInfo->memdc,hOldBrush); DrawIconToMemBmp(WndNum,0); InvalidateRect(MdiInfo[WndNum].MdiIconEditInfo->hMain,NULL,1); InvalidateRect(MdiInfo[WndNum].MdiIconEditInfo->hColorDlg,NULL,0); } void DeleteIconType(int WndNum){ extern MDIINFO MdiInfo[MAX_WNDNUM]; int i; //変更情報を解放 for(i=0;iundo[MdiInfo[WndNum].MdiIconEditInfo->SelectIconNum].lpData[i]) HeapDefaultFree(MdiInfo[WndNum].MdiIconEditInfo->undo[MdiInfo[WndNum].MdiIconEditInfo->SelectIconNum].lpData[i]); } //メモリを解放 HeapDefaultFree(MdiInfo[WndNum].MdiIconEditInfo->pIconImage[MdiInfo[WndNum].MdiIconEditInfo->SelectIconNum]); //イメージ選択用のメモリを解放 if(MdiInfo[WndNum].MdiIconEditInfo->SelectLevel==2) DeleteObject(MdiInfo[WndNum].MdiIconEditInfo->hSelectingBmp); MdiInfo[WndNum].MdiIconEditInfo->SelectLevel=0; //////////////////////// // アイコンタイプを削除 for(i=MdiInfo[WndNum].MdiIconEditInfo->SelectIconNum;inum-1;i++){ MdiInfo[WndNum].MdiIconEditInfo->pIconImage[i]=MdiInfo[WndNum].MdiIconEditInfo->pIconImage[i+1]; MdiInfo[WndNum].MdiIconEditInfo->dwBytesInRes[i]=MdiInfo[WndNum].MdiIconEditInfo->dwBytesInRes[i+1]; MdiInfo[WndNum].MdiIconEditInfo->undo[i]=MdiInfo[WndNum].MdiIconEditInfo->undo[i+1]; } MdiInfo[WndNum].MdiIconEditInfo->num--; if(MdiInfo[WndNum].MdiIconEditInfo->num==MdiInfo[WndNum].MdiIconEditInfo->SelectIconNum) MdiInfo[WndNum].MdiIconEditInfo->SelectIconNum=MdiInfo[WndNum].MdiIconEditInfo->num-1; //コンボボックスからアイコンタイプを削除 HWND hCombo; hCombo=GetDlgItem(MdiInfo[WndNum].MdiIconEditInfo->hToolDlg,IDC_ICONTYPECOMBO); i=SendMessage(hCombo,CB_DELETESTRING, SendMessage(hCombo,CB_GETCURSEL,0,0), 0); SendMessage(hCombo,CB_SETCURSEL,MdiInfo[WndNum].MdiIconEditInfo->SelectIconNum,0); //再描画 HBRUSH hOldBrush; hOldBrush=(HBRUSH)SelectObject(MdiInfo[WndNum].MdiIconEditInfo->memdc,GetStockObject(WHITE_BRUSH)); PatBlt(MdiInfo[WndNum].MdiIconEditInfo->memdc,0,0,400,400,PATCOPY); SelectObject(MdiInfo[WndNum].MdiIconEditInfo->memdc,hOldBrush); DrawIconToMemBmp(WndNum,0); InvalidateRect(MdiInfo[WndNum].MdiIconEditInfo->hMain,NULL,1); InvalidateRect(MdiInfo[WndNum].MdiIconEditInfo->hColorDlg,NULL,0); } void NewIconEditWindow(const char *filepath){ extern HINSTANCE hInst,hResInst; extern HANDLE hHeap; extern HWND hDocCombo; extern MDIINFO MdiInfo[MAX_WNDNUM]; int i,i2,IconNum; char str[MAX_PATH],str2[32],*buffer; BYTE *pImageBuffer[8]; DWORD dwBytesInRes[8]; HWND hChild; HDC hdc; MDICREATESTRUCT mdic; if(filepath){ //すでに指定されたファイルが開かれている場合 hChild=GetWindow(hClient,GW_CHILD); while(hChild){ i=GetWndNum(hChild); if(MdiInfo[i].DocType==WNDTYPE_ICONEDIT){ if(lstrcmpi(MdiInfo[i].path,filepath)==0) break; } hChild=GetNextWindow(hChild,GW_HWNDNEXT); } if(hChild){ BringWindowToTop(hChild); return; } //ファイル読み込み(正常に読み込めるかの確認も含む) HANDLE hFile; DWORD dw; hFile=CreateFile(filepath,GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if(hFile==INVALID_HANDLE_VALUE){ //"\"%s\" ファイルの読み込みに失敗しました。" sprintf(str,STRING_ERROR_CANT_FILEOPEN,filepath); MessageBox(hOwner,str,STRING_ERROR,MB_OK|MB_ICONEXCLAMATION); return; } i=GetFileSize(hFile,NULL); buffer=(char *)HeapAlloc(hHeap,0,i+1); ReadFile(hFile,buffer,i,&dw,NULL); CloseHandle(hFile); ICONDIR *pIconDir; ICONDIRENTRY *pIconDirEntry; pIconDir=(ICONDIR *)buffer; IconNum=pIconDir->idCount; bool FileOk = true; for(i=0;idwBytesInRes); memcpy(pImageBuffer[i],buffer+pIconDirEntry->dwImageOffset,pIconDirEntry->dwBytesInRes); dwBytesInRes[i]=pIconDirEntry->dwBytesInRes; //対応チェック BITMAPINFOHEADER *pBmpInfoHdr=(BITMAPINFOHEADER *)pImageBuffer[i]; if( !(pBmpInfoHdr->biBitCount == 4 || pBmpInfoHdr->biBitCount == 8 ) ){ //16色、256色以外の場合 //未対応 FileOk = false; } } _splitpath(filepath,NULL,NULL,str,str2); lstrcat(str,str2); mdic.szTitle=str; HeapDefaultFree(buffer); if( !FileOk ){ for(i=0;ibMDIZoomed) mdic.style=WS_MAXIMIZE; else mdic.style=0; } mdic.lParam=0; hChild=(HWND)SendMessage(hClient,WM_MDICREATE,0,(long)&mdic); //ウィンドウ作成 //////////////////// //子ウィンドウ作成 //エディタ中央部分を作成 HWND hMain; hMain=CreateWindowEx(WS_EX_CLIENTEDGE,"IconEditWindowProc",NULL, WS_CHILD|WS_VISIBLE, 0,0,0,0, hChild,NULL,hInst,NULL); //ツールダイアログ部分を作成 HWND hToolDlg; hToolDlg=CreateDialog(hResInst,MAKEINTRESOURCE(IDD_ICONEDIT_TOOL),hChild,(DLGPROC)DlgIconToolProc); //ツールダイアログのボタン部分を作成 HWND hButtonsDlg; hButtonsDlg=CreateDialog(hResInst,MAKEINTRESOURCE(IDD_ICONEDIT_BUTTONS),hToolDlg,(DLGPROC)DlgIconButtons); //カラーテーブルダイアログ部分を作成 HWND hColorDlg; hColorDlg=CreateDialog(hResInst,MAKEINTRESOURCE(IDD_ICONEDIT_COLOR),hChild,(DLGPROC)DlgIconColorProc); //ウィンドウのID登録 for(i=0;ihMain=hMain; MdiInfo[i].MdiIconEditInfo->hToolDlg=hToolDlg; MdiInfo[i].MdiIconEditInfo->hButtonsDlg=hButtonsDlg; MdiInfo[i].MdiIconEditInfo->hColorDlg=hColorDlg; hdc=GetDC(hMain); MdiInfo[i].MdiIconEditInfo->memdc=CreateCompatibleDC(hdc); MdiInfo[i].MdiIconEditInfo->hMemBmp=CreateCompatibleBitmap(hdc,600,400); SelectObject(MdiInfo[i].MdiIconEditInfo->memdc,MdiInfo[i].MdiIconEditInfo->hMemBmp); ReleaseDC(hMain,hdc); MdiInfo[i].MdiIconEditInfo->SelectLevel=0; MdiInfo[i].MdiIconEditInfo->num=IconNum; MdiInfo[i].MdiIconEditInfo->SelectIconNum=0; memcpy(MdiInfo[i].MdiIconEditInfo->pIconImage,pImageBuffer,sizeof(DWORD)*IconNum); memcpy(MdiInfo[i].MdiIconEditInfo->dwBytesInRes,dwBytesInRes,sizeof(DWORD)*IconNum); MdiInfo[i].MdiIconEditInfo->NowTool=IDC_TOOL_PEN; MdiInfo[i].MdiIconEditInfo->MainColor=RGB(0,0,0); extern COLORREF TransparentClrRef; MdiInfo[i].MdiIconEditInfo->SubColor=TransparentClrRef; for(i2=0;i2num;i2++){ MdiInfo[i].MdiIconEditInfo->undo[i2].NowPos=0; memset(MdiInfo[i].MdiIconEditInfo->undo[i2].lpData,0,sizeof(BYTE *)*MAX_ICONEDIT_UNDONUM); } MdiInfo[i].MdiIconEditInfo->bModify=0; break; } } //メモリへ初期描画を行う HBRUSH hOldBrush; hOldBrush=(HBRUSH)SelectObject(MdiInfo[i].MdiIconEditInfo->memdc,GetStockObject(WHITE_BRUSH)); PatBlt(MdiInfo[i].MdiIconEditInfo->memdc,0,0,600,400,PATCOPY); SelectObject(MdiInfo[i].MdiIconEditInfo->memdc,hOldBrush); DrawIconToMemBmp(i,0); //ウィンドウ位置を初期化 RECT rc; GetClientRect(hChild,&rc); ResizeIconWindow(hMain,hToolDlg,hColorDlg,rc.right,rc.bottom); //アイコンタイプコンボボックスをセット ResetIconType(i); if(MdiInfo[i].MdiIconEditInfo->num<=1) EnableWindow(GetDlgItem(hToolDlg,IDC_DELETE_ICONTYPE),0); //Docコンボボックスに追加 i=SendMessage(hDocCombo,CB_ADDSTRING,0,(long)str); SendMessage(hDocCombo,CB_SETCURSEL,i,0); //タブに追加 pobj_MainTab->InsertItem( str, true ); SetStatusText(NULL); //メニュー状態を設定 ResetState_DocMenu(); } void SaveIconFile(char *filepath,HWND hwnd){ extern MDIINFO MdiInfo[MAX_WNDNUM]; int i,i2,WndNum; char buffer[8192],temporary[MAX_PATH]; int ImgBufSize[8]; WndNum=GetWndNum(hwnd); i2=0; /////////// // ICONDIR *((WORD *)(buffer+i2))=0; //idReserved i2+=sizeof(WORD); *((WORD *)(buffer+i2))=1; //idType i2+=sizeof(WORD); *((WORD *)(buffer+i2))=MdiInfo[WndNum].MdiIconEditInfo->num; //idCount i2+=sizeof(WORD); //////////////// // ICONDIRENTRY ICONDIRENTRY IconDirEntry; memset(&IconDirEntry,0,sizeof(ICONDIRENTRY)); //イメージバッファの初期位置 IconDirEntry.dwImageOffset=sizeof(ICONDIR)+ sizeof(ICONDIRENTRY)*MdiInfo[WndNum].MdiIconEditInfo->num; for(i=0;inum;i++){ BITMAPINFOHEADER *pBmpInfoHdr; pBmpInfoHdr=(BITMAPINFOHEADER *)MdiInfo[WndNum].MdiIconEditInfo->pIconImage[i]; IconDirEntry.bWidth=(BYTE)pBmpInfoHdr->biWidth; IconDirEntry.bHeight=(BYTE)pBmpInfoHdr->biHeight/2; if(pBmpInfoHdr->biBitCount<=8) IconDirEntry.bColorCount=(BYTE)pow((double)2,(double)pBmpInfoHdr->biBitCount); else IconDirEntry.bColorCount=0; IconDirEntry.dwBytesInRes=sizeof(BITMAPINFOHEADER); if(pBmpInfoHdr->biBitCount<=8) //256色以下の場合はカラーパレットのサイズを考慮 IconDirEntry.dwBytesInRes+=(DWORD)pow((double)2,(double)pBmpInfoHdr->biBitCount)*sizeof(long); IconDirEntry.dwBytesInRes+=pBmpInfoHdr->biBitCount*pBmpInfoHdr->biWidth*(pBmpInfoHdr->biHeight/2)/8; if(pBmpInfoHdr->biWidth==16){ //16*16のアイコン IconDirEntry.dwBytesInRes+=pBmpInfoHdr->biWidth*(pBmpInfoHdr->biHeight/2)/8*2; } else{ //32*32のアイコン IconDirEntry.dwBytesInRes+=pBmpInfoHdr->biWidth*(pBmpInfoHdr->biHeight/2)/8; } ImgBufSize[i]=IconDirEntry.dwBytesInRes; memcpy(buffer+i2,&IconDirEntry,sizeof(ICONDIRENTRY)); i2+=sizeof(ICONDIRENTRY); IconDirEntry.dwImageOffset+=IconDirEntry.dwBytesInRes; } //////////////////// // イメージバッファ for(i=0;inum;i++){ memcpy(buffer+i2, MdiInfo[WndNum].MdiIconEditInfo->pIconImage[i], ImgBufSize[i]); i2+=ImgBufSize[i]; } //ファイルへ書き込み HANDLE hFile; DWORD dummy; hFile=CreateFile(filepath,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); if(hFile==INVALID_HANDLE_VALUE){ //"\"%s\" ファイルへの書き込みに失敗しました。" sprintf(temporary,STRING_ERROR_CANT_FILESAVE,filepath); MessageBox(hOwner,temporary,STRING_ERROR,MB_OK|MB_ICONSTOP); return; } WriteFile(hFile,buffer,i2,&dummy,NULL); CloseHandle(hFile); } LRESULT CALLBACK MDIClientWindow_IconEdit(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam){ extern HWND hDocCombo; extern MDIINFO MdiInfo[MAX_WNDNUM]; int i,WndNum; switch(message){ case WM_MDIACTIVATE: if(!lParam) return 0; i=GetWndNum((HWND)lParam); if(i==-1) return 0; //ウィンドウが初期状態の場合 i=SendMessage(hDocCombo,CB_FINDSTRINGEXACT,0,(long)MdiInfo[i].title); SendMessage(hDocCombo,CB_SETCURSEL,i,0); SetStatusText(NULL); ResetState_EditMenu(); return 0; case WM_SIZE: WndNum=GetWndNum(hwnd); if(WndNum==-1) break; ResizeIconWindow(MdiInfo[WndNum].MdiIconEditInfo->hMain, MdiInfo[WndNum].MdiIconEditInfo->hToolDlg, MdiInfo[WndNum].MdiIconEditInfo->hColorDlg, LOWORD(lParam),HIWORD(lParam)); break; case WM_CLOSE: CloseDocWindow(GetWndNum(hwnd)); pobj_nv->bMDIZoomed=IsZoomed(hwnd); i=DefMDIChildProc(hwnd,message,wParam,lParam); //メニュー状態を設定 ResetState_DocMenu(); return i; } return DefMDIChildProc(hwnd,message,wParam,lParam); }