?? fractalexview.cpp
字號:
GetObject(hbitmap, sizeof(bitmap), (LPSTR)&bitmap);
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = bitmap.bmWidth;
bi.biHeight = bitmap.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = wbitcount;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
dwbmbitssize = ((bitmap.bmWidth * wbitcount+31)/32)* 4 * bitmap.bmHeight;
//為位圖內容分配內存
hdib = GlobalAlloc(GHND,dwbmbitssize+dwpalettesize+sizeof(BITMAPINFOHEADER));
lpbi = (LPBITMAPINFOHEADER)GlobalAlloc(hdib);
*lpbi = bi;
// 處理調色板
hpal = getstockobject(default_palette);
if (hpal)
{
hdc = getdc(null);
holdpal = selectpalette(hdc, hpal, false);
realizepalette(hdc);
}
// 獲取該調色板下新的像素值
getdibits(hdc, hbitmap, 0, (uint) bitmap.bmheight,
(lpstr)lpbi + sizeof(bitmapinfoheader)
+dwpalettesize,
(bitmapinfoheader *)
lpbi, dib_rgb_colors);
//恢復調色板
if (holdpal)
{
selectpalette(hdc, holdpal, true);
realizepalette(hdc);
releasedc(null, hdc);
}
//創建位圖文件
fh = createfile(lpfilename, generic_write,
0, null, create_always,
file_attribute_normal | file_
flag_sequential_scan, null);
if (fh == invalid_handle_value)
return false;
// 設置位圖文件頭
bmfhdr.bftype = 0x4d42; // "bm"
dwdibsize = sizeof(bitmapfileheader)
+ sizeof(bitmapinfoheader)
+ dwpalettesize + dwbmbitssize;
bmfhdr.bfsize = dwdibsize;
bmfhdr.bfreserved1 = 0;
bmfhdr.bfreserved2 = 0;
bmfhdr.bfoffbits = (dword)sizeof
(bitmapfileheader)
+ (dword)sizeof(bitmapinfoheader)
+ dwpalettesize;
// 寫入位圖文件頭
writefile(fh, (lpstr)&bmfhdr, sizeof
(bitmapfileheader), &dwwritten, null);
// 寫入位圖文件其余內容
writefile(fh, (lpstr)lpbi, dwdibsize,
&dwwritten, null);
//清除
globalunlock(hdib);
globalfree(hdib);
closehandle(fh);/**/
}
void CFractalExView::OnEditCopy()//把圖象放入剪貼板
{
CClientDC dc(this);
CDC memdc;
memdc.CreateCompatibleDC(&dc);
CBitmap bm;
bm.CreateCompatibleBitmap(&dc, wid2, hei2);
CBitmap* oldbm=memdc.SelectObject(&bm);
memdib.CopyDC(&memdc, 0, 0);
memdc.SelectObject(oldbm);
if (OpenClipboard())
{
EmptyClipboard();
SetClipboardData(CF_BITMAP, bm.GetSafeHandle());
CloseClipboard();
}
bm.DeleteObject();
memdc.DeleteDC();
}
void CFractalExView::DrawFractal(bool redraw)
{
if(CalcFractal==NULL)
return;
CWaitCursor wait;
CRectFloat& myRect=GetDocument()->myRect;
datatype mag=2.0/(myRect.bottom-myRect.top);
int lvl=GetDocument()->iteration;
strlvl.Format("%d_X_%g", lvl, mag);
GetDocument()->SetTitle(strlvl);
CRect rect;
GetClientRect(&rect);
scale=(myRect.bottom-myRect.top)/hei2;
memdib.Fill(255,255,255);
widhei=(datatype)hei2/wid2;
DWORD time1=GetTickCount();
memset(pixelinfo, 0, sizeof(PixelInfo)*wid2*hei2);
if(CalcFractalPoint==NULL)
CalcFractal(pixelinfo, myRect.left, myRect.top, scale, wid2, hei2, lvl);
else
{
datatype left=myRect.left, top=myRect.top;
PixelInfo *info;
int x, y, countxy;
datatype x0 = 0, y0 = 0, x1 = 0, y1 = 0;
switch(GetDocument()->fractalmode)
{
case FRACTAL_MODE_MAND:
for (y = 0 ; y<hei2;y++)
for (x = 0 ;x < wid2; x++)
{
countxy=x+(hei2-y-1)*wid2;
info=pixelinfo+countxy;
x0=x*scale + left;
y0=y*scale + top;
info->lvl=CalcFractalPoint(x1, y1, x0, y0);
}
break;
case FRACTAL_MODE_JULIA:
x1=GetDocument()->JuliaSeed.x;
y1=GetDocument()->JuliaSeed.y;
for (y = 0 ; y<hei2;y++)
for (x = 0 ;x < wid2; x++)
{
countxy=x+(hei2-y-1)*wid2;
info=pixelinfo+countxy;
x0=x*scale + left;
y0=y*scale + top;
info->lvl=CalcFractalPoint(x0, y0, x1, y1);
}
break;
case FRACTAL_MODE_PERT:
x1=GetDocument()->Perturbation.x;
y1=GetDocument()->Perturbation.y;
for (y = 0 ; y<hei2;y++)
for (x = 0 ;x < wid2; x++)
{
countxy=x+(hei2-y-1)*wid2;
info=pixelinfo+countxy;
x0=x*scale + left;
y0=y*scale + top;
info->lvl=CalcFractalPoint(x1, y1, x0, y0);
}
break;
default:
break;
}
}
DWORD time2=GetTickCount();
Render();
if(redraw)
{
CClientDC dc(this);
memdib.CopyDC(&dc, 0, 0);
}
// DWORD time3=GetTickCount();
// CString str;
// str.Format("%d, %d", time3-time1, time3-time2);
// MessageBox(str);
}
void CFractalExView::NewFractal(CRectFloat& rc)
{
CDocTemplate* pTemplate = ((CFractalExApp*)AfxGetApp())->pDocTemplate1;
CDocument* doc=pTemplate->CreateNewDocument();
((CFractalExDoc*)doc)->SetData(GetDocument());
CFrameWnd* pFrame=pTemplate->CreateNewFrame(doc, NULL);
pTemplate->InitialUpdateFrame(pFrame, doc);
}
void CFractalExView::OnOnidle()
{
return;
if(CalcFractal==NULL)
return;
CRectFloat& myRect=GetDocument()->myRect;
const int idlelvl=50;//空閑的時候算多少遍
if(mousedown)
return;
CalcFractal(pixelinfo, myRect.left, myRect.top, scale, wid2, hei2, idlelvl);
Render();
CClientDC dc(this);
memdib.CopyDC(&dc, 0, 0);
}
void CFractalExView::OnUpdateFractaltype(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck((int)pCmdUI->m_nID-ID_FRACTAL_FIRST==GetDocument()->fType);
}
void CFractalExView::OnFractaltype(UINT nID)
{
GetDocument()->ResetRect();
LoadFractalLib(LibPath+PreLoadLib[nID-ID_FRACTAL_FIRST]);
GetDocument()->fType=nID-ID_FRACTAL_FIRST;
}
void CFractalExView::OnFractalCustom()
{
if(customfdlg.DoModal()==IDOK)
{
CString temp=BuildDll(customfdlg.m_expression, customfdlg.m_origin, customfdlg.m_name, customfdlg.tempor!=0);
if(temp!="")
{
GetDocument()->ResetRect();
LoadFractalLib(temp);
GetDocument()->fType=FRACTAL_CUSTOM;
}
else
MessageBox("輸入錯誤,無法進行迭代。");
}
}
void CFractalExView::OnFractalOther()
{
if(otherfdlg.DoModal()==IDOK)
{
GetDocument()->ResetRect();
LoadFractalLib(otherfdlg.SelectedLib);
GetDocument()->fType=FRACTAL_OTHER;
}
}
void CFractalExView::OnUpdateFractalOther(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck(GetDocument()->fType==FRACTAL_OTHER);
}
void CFractalExView::OnUpdateFractalCustom(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck(GetDocument()->fType==FRACTAL_CUSTOM);
}
void CFractalExView::OnUpdateColorset(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck((int)pCmdUI->m_nID-ID_COLOR_SET0==GetDocument()->colorset);
}
void CFractalExView::OnColorset(UINT nID)
{
UseColorSet(nID-ID_COLOR_SET0);
}
void CFractalExView::UseColorSet(int set, bool redraw)
{
GetDocument()->colorset=set;
int i, n=0;
int colorbase=55;
switch(set)
{
case 0:
//色圈
for(i=colorbase;i<255;i++)
{
colorcir[n]=RGB(i, 255, colorbase);
n++;
}
for(i=colorbase;i<255;i++)
{
colorcir[n]=RGB(255, 255-i+colorbase, colorbase);
n++;
}
for(i=colorbase;i<255;i++)
{
colorcir[n]=RGB(255, colorbase, i);
n++;
}
for(i=colorbase;i<255;i++)
{
colorcir[n]=RGB(255-i+colorbase, colorbase, 255);
n++;
}
for(i=colorbase;i<255;i++)
{
colorcir[n]=RGB(colorbase, i, 255);
n++;
}
for(i=colorbase;i<255;i++)
{
colorcir[n]=RGB(colorbase, 255, 255-i+colorbase);
n++;
}
break;
case 1:
for(i=colorbase;i<255;i++)
{
colorcir[n]=RGB(i, colorbase, colorbase);
n++;
}
for(i=colorbase;i<255;i++)
{
colorcir[n]=RGB(i, i, colorbase);
n++;
}
for(i=colorbase;i<255;i++)
{
colorcir[n]=RGB(colorbase, i, colorbase);
n++;
}
for(i=colorbase;i<255;i++)
{
colorcir[n]=RGB(colorbase, i, i);
n++;
}
for(i=colorbase;i<255;i++)
{
colorcir[n]=RGB(colorbase, colorbase, i);
n++;
}
for(i=colorbase;i<255;i++)
{
colorcir[n]=RGB(i, colorbase, i);
n++;
}
break;
}
if(redraw)
{
CClientDC dc(this);
Render();
memdib.CopyDC(&dc, 0, 0);
}
}
void CFractalExView::Render()//根據pixelinfo把顏色寫入dib
{
for (int x = 0 ;x < wid2; x++)
for (int y = 0 ; y<hei2;y++)
{
int countxy=x+(hei2-y-1)*wid2;
PixelInfo* info=pixelinfo+countxy;
if(info->lvl>=0)
{
int t = info->lvl;
if(t<20)
memdib.m_Bits[countxy]=RGB(0, t*10+60, 0);
else
memdib.m_Bits[countxy]=colorcir[(t-20)%60*20];
}
}
}
void CFractalExView::LoadFractalLib(CString dllname)
{
UnloadFractalLib();
if(dllname!="")
{
BuildLib=dllname;
hlib=LoadLibrary(dllname);
if(hlib)
{
CalcFractal=(_CalcFractal)GetProcAddress(hlib, "CalcFractal");
GetFractalData=(_GetFractalData)GetProcAddress(hlib, "GetFractalData");
CalcFractalPoint=(_CalcFractalPoint)GetProcAddress(hlib, "CalcFractalPoint");
}
DrawFractal();
}
}
CString CFractalExView::BuildDll(CString exp, CString ori, CString name, bool tempor)//tempor是否需要保留該dll
{
CString strFile, strPath, temp;
GetDocument()->expression=exp;
GetDocument()->origin=ori;
strPath=LibPath;
CFileFind cfd;
int i=-1;
do
i++;
temp.Format("frc%04d.dll", i);
strFile=strPath+temp;
}
while(cfd.FindFile(strFile));
//寫入cpp
CFile file(strPath+"custom.cpp", CFile::modeCreate | CFile::modeWrite);
file.Write(CodeRes1,CodeSize1);
/*寫變量*/
temp="FractalData fractaldata={";
temp+="\""+exp+"\", ";
temp+="\""+ori+"\", ";
temp+="\""+name+"\", ";
if(tempor)
temp+="true";
else
temp+="false";
temp+="};\n";
file.Write(temp, temp.GetLength());
/*******/
exp=_T("z=")+exp+_T(";\n");
ori=_T("z=")+ori+_T(";\n");
file.Write(CodeRes4,CodeSize4);
file.Write(ori, ori.GetLength());
file.Write(CodeRes2,CodeSize2);
file.Write(exp, exp.GetLength());
file.Write(CodeRes3,CodeSize3);
file.Close();
//編譯這個cpp
STARTUPINFO StartupInfo;
memset(&StartupInfo, 0, sizeof(STARTUPINFO));
StartupInfo.cb = sizeof(STARTUPINFO);
PROCESS_INFORMATION ProcessInfo;
StartupInfo.dwFlags=STARTF_USESHOWWINDOW;
StartupInfo.wShowWindow=SW_HIDE;
CString cmdline("cl.exe custom.cpp /GX /O2 /c \n");
CreateProcess(NULL, cmdline.GetBuffer(MAX_PATH), NULL, NULL,FALSE, 0, NULL, strPath, &StartupInfo, &ProcessInfo );
WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
cmdline="link.exe custom.obj /dll /out:\""+strFile+"\"";
CreateProcess(NULL, cmdline.GetBuffer(MAX_PATH), NULL, NULL,FALSE, 0, NULL, strPath, &StartupInfo, &ProcessInfo );
WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
// DeleteFile(strPath+"custom.cpp");
DeleteFile(strPath+"custom.obj");
temp=strFile.Left(strFile.ReverseFind('.')+1);
DeleteFile(temp+"lib");
DeleteFile(temp+"exp");
if(cfd.FindFile(strFile))
return strFile;
else
return "";
}
void CFractalExView::UnloadFractalLib()
{
bool tempor=false;
if(GetFractalData)
{
FractalData* data=GetFractalData();
tempor=data->tempor;
}
if(hlib)//先釋放前一個dll
FreeLibrary(hlib);
if(BuildLib!=""&&!tempor)
{
DeleteFile(BuildLib);
}
hlib=0;
BuildLib="";
CalcFractal=NULL;
GetFractalData=NULL;
CalcFractalPoint=NULL;
}
CMainFrame* CFractalExView::GetMainFrame()
{
return (CMainFrame*) AfxGetMainWnd();
}
void CFractalExView::OnUpdateCoorIndicator(CCmdUI* pCmdUI)
{
pCmdUI->SetText(status_coor);
}
void CFractalExView::OnSetIteration()
{
CIterationDialog dlg;
dlg.m_iter=GetDocument()->iteration;
if(dlg.DoModal()==IDOK&&dlg.m_iter!=GetDocument()->iteration)
{
GetDocument()->iteration=dlg.m_iter;
DrawFractal();
}
}
void CFractalExView::OnFractalViewinfo()
{
CInfoDialog dlg;
dlg.m_left=GetDocument()->myRect.left;
dlg.m_right=GetDocument()->myRect.right;
dlg.m_top=GetDocument()->myRect.top;
dlg.m_bottom=GetDocument()->myRect.bottom;
if(dlg.DoModal()==IDOK)
{
GetDocument()->myRect.left=dlg.m_left;
GetDocument()->myRect.right=dlg.m_right;
GetDocument()->myRect.top=dlg.m_top;
GetDocument()->myRect.bottom=dlg.m_bottom;
DrawFractal();
}
}
void CFractalExView::OnUpdateFractalModeJulia(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck(GetDocument()->fractalmode==FRACTAL_MODE_JULIA);
}
void CFractalExView::OnUpdateFractalModeMand(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck(GetDocument()->fractalmode==FRACTAL_MODE_MAND);
}
void CFractalExView::OnUpdateFractalModePert(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck(GetDocument()->fractalmode==FRACTAL_MODE_PERT);
}
void CFractalExView::OnFractalModeJulia()
{
CJuliaDialog dlg;
dlg.m_real=GetDocument()->JuliaSeed.x;
dlg.m_image=GetDocument()->JuliaSeed.y;
if(dlg.DoModal()==IDOK)
{
GetDocument()->ResetRect();
GetDocument()->JuliaSeed.x=dlg.m_real;
GetDocument()->JuliaSeed.y=dlg.m_image;
GetDocument()->fractalmode=FRACTAL_MODE_JULIA;
DrawFractal();
}
}
void CFractalExView::OnFractalModeMand()
{
GetDocument()->ResetRect();
GetDocument()->fractalmode=FRACTAL_MODE_MAND;
DrawFractal();
}
void CFractalExView::OnFractalModePert()
{
CPertDialog dlg;
dlg.m_real=GetDocument()->Perturbation.x;
dlg.m_image=GetDocument()->Perturbation.y;
if(dlg.DoModal()==IDOK)
{
GetDocument()->ResetRect();
GetDocument()->Perturbation.x=dlg.m_real;
GetDocument()->Perturbation.y=dlg.m_image;
GetDocument()->fractalmode=FRACTAL_MODE_PERT;
DrawFractal();
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -