#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){ int i; HWND hCombo; char temporary[MAX_PATH]; BITMAPINFOHEADER *pBmpInfoHdr; hCombo=GetDlgItem(MdiInfo[WndNum]->MdiIconEditInfo->hToolDlg,IDC_ICONTYPECOMBO); for(i=0;iMdiIconEditInfo->num;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; 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){ int i; //変更情報を解放 for(i=0;iMdiIconEditInfo->undo[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;iMdiIconEditInfo->num-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; 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.c_str(),filepath)==0) break; } hChild=GetNextWindow(hChild,GW_HWNDNEXT); } if(hChild){ BringWindowToTop(hChild); return; } //ファイル読み込み(正常に読み込めるかの確認も含む) { DWORD dw; ATL::CHandle hFile(CreateFile(filepath,GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL)); if(hFile==INVALID_HANDLE_VALUE){ hFile.Detach(); //"\"%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); } 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; mdic.style |= WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_SYSMENU | WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX; hChild=(HWND)SendMessage(hClient,WM_MDICREATE,0,(LPARAM)&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=ActiveBasic::Resource::CreateDialogAlt(hResInst, IDD_ICONEDIT_TOOL, hChild, DlgIconToolProc); //ツールダイアログのボタン部分を作成 HWND hButtonsDlg; hButtonsDlg=ActiveBasic::Resource::CreateDialogAlt(hResInst, IDD_ICONEDIT_BUTTONS, hToolDlg, DlgIconButtons); //カラーテーブルダイアログ部分を作成 HWND hColorDlg; hColorDlg=ActiveBasic::Resource::CreateDialogAlt(hResInst, IDD_ICONEDIT_COLOR, hChild, DlgIconColorProc); //ウィンドウのID登録 MdiInfo.push_back( new MDIINFO() ); i = MdiInfo.size()-1; MdiInfo[i]->hwnd=hChild; MdiInfo[i]->DocType=WNDTYPE_ICONEDIT; MdiInfo[i]->title = str; if(filepath) { MdiInfo[i]->path = filepath; } else { MdiInfo[i]->path = ""; } MdiInfo[i]->MdiIconEditInfo=(MDIICONEDITINFO *)HeapAlloc(hHeap,0,sizeof(MDIICONEDITINFO)); MdiInfo[i]->MdiIconEditInfo->hMain=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;i2MdiIconEditInfo->num;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; //メモリへ初期描画を行う 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( hChild, str, true ); SetStatusText(NULL); //メニュー状態を設定 ResetState_DocMenu(); } void SetFileIdentityFromFile(MDIINFO &mi, HANDLE hFile); void SaveIconFile(char *filepath,HWND hwnd){ 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;iMdiIconEditInfo->num;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;iMdiIconEditInfo->num;i++){ memcpy(buffer+i2, MdiInfo[WndNum]->MdiIconEditInfo->pIconImage[i], ImgBufSize[i]); i2+=ImgBufSize[i]; } //ファイルへ書き込み DWORD dummy; ATL::CHandle hFile(CreateFile(filepath,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL)); if(hFile==INVALID_HANDLE_VALUE){ hFile.Detach(); //"\"%s\" ファイルへの書き込みに失敗しました。" sprintf(temporary,STRING_ERROR_CANT_FILESAVE,filepath); MessageBox(hOwner,temporary,STRING_ERROR,MB_OK|MB_ICONSTOP); return; } WriteFile(hFile,buffer,i2,&dummy,NULL); SetFileIdentityFromFile(*MdiInfo[WndNum], hFile); } LRESULT CALLBACK MDIClientWindow_IconEdit(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam){ extern HWND hDocCombo; 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.c_str()); 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); }