精通
英语
和
开源
,
擅长
开发
与
培训
,
胸怀四海
第一信赖
锐英源精品独创开源文章,禁止任何形式的转载和任何形式的非法使用,侵权必究
MFCPlugIn是Filter类型的插件,生成的插件文件是MFCPlugIn.8bf,把这个文件拷贝到photoshop的插件目录的Filters目录下即可使用。打开后,显示个对话框,对话框左上角显示客户区位置,输入新值后,会把新值属性修改后的位置再显示到PS客户区的左上角。
要想理解功能,首先要理解插件的入口函数:PluginMain,和PS环境交互有些标准动作,动作对应的类型都有定义,比如filterSelectorParameters是关于参数的,在本例子里,代码:
case filterSelectorParameters: theApp.Parameters(); break;
Parameters()函数调用时,会使用m_Value,而这个值就是来自于对话框。而对话框的打开和显示是在DoUI函数,而DoUI函数是在:
case filterSelectorStart: theApp.Start(); break;
在这个Start()里调用的。相当于启动时,显示界面,界面关闭时,更新参数。
在对话框里显示客户区的位置是通过先设置,再绘制实现的。设置函数为:
void MyMFCDialog::SetupFilterRecordForProxy () { CalcProxyScaleFactor(); m_pFilterRecord->inRect.top = (short)m_ProxyRect.top; m_pFilterRecord->inRect.left = (short)m_ProxyRect.left; m_pFilterRecord->inRect.bottom = (short)m_ProxyRect.bottom; m_pFilterRecord->inRect.right = (short)m_ProxyRect.right; m_pFilterRecord->maskRect = m_pFilterRecord->outRect = m_pFilterRecord->inRect; m_pFilterRecord->inLoPlane = m_pFilterRecord->outLoPlane = 0; m_pFilterRecord->inHiPlane = m_pFilterRecord->outHiPlane = m_pFilterRecord->planes - 1; m_pFilterRecord->inputRate = m_ScaleFactor << 16; m_pFilterRecord->maskRate = m_pFilterRecord->inputRate; m_pFilterRecord->inputPadding = 255; m_pFilterRecord->outputPadding = m_pFilterRecord->inputPadding; m_pFilterRecord->maskPadding = m_pFilterRecord->inputPadding; if ((*m_pFilterRecord->advanceState)()) { throw((char*)"advanceState no go!"); } // copy the input buffer to the output buffer // we will put our effect into the outData buffer for // proxy view updates把输入缓冲拷贝到输出缓冲,就可以支持proxy窗口显示了。 memcpy(m_pFilterRecord->outData, m_pFilterRecord->inData, (m_pFilterRecord->planes * m_pFilterRecord->inRect.bottom * m_pFilterRecord->inRect.right)); }
显示代码是:
void MyMFCDialog::OnPaint() { CPaintDC dc(this); // device context for painting // we need to display our current buffer in the proxy view PSPixelMap pixels; pixels.version = 1; pixels.bounds.top = m_pFilterRecord->outRect.top; pixels.bounds.left = m_pFilterRecord->outRect.left; pixels.bounds.bottom = m_pFilterRecord->outRect.bottom; pixels.bounds.right = m_pFilterRecord->outRect.right; pixels.imageMode = m_pFilterRecord->imageMode; pixels.rowBytes = m_pFilterRecord->outRowBytes; pixels.colBytes = m_pFilterRecord->outHiPlane - m_pFilterRecord->outLoPlane + 1; pixels.planeBytes = 1; // for now it will be inData, DoFilterRect in Dissolve Sans // copies the inData to the outData with the effect // we are only showing the original for now, man that is confusing pixels.baseAddr = m_pFilterRecord->outData; pixels.mat = NULL; pixels.masks = NULL; pixels.maskPhaseRow = 0; pixels.maskPhaseCol = 0; PSPixelMask mask; if (m_pFilterRecord->isFloating) { mask.next = NULL; mask.maskData = m_pFilterRecord->maskData; mask.rowBytes = m_pFilterRecord->maskRowBytes; mask.colBytes = 1; mask.maskDescription = kSimplePSMask; } else if ((m_pFilterRecord->inLayerPlanes != 0) && (m_pFilterRecord->inTransparencyMask != 0)) { mask.next = NULL; mask.maskData = m_pFilterRecord->maskData; mask.rowBytes = m_pFilterRecord->outRowBytes; mask.colBytes = m_pFilterRecord->outHiPlane - m_pFilterRecord->outLoPlane + 1; mask.maskDescription = kSimplePSMask; pixels.masks = &mask; } CWnd* pWnd = GetDlgItem(IDC_PROXY); if (pWnd == NULL) throw((char*)"No pWnd in MyMFCDialog::OnPaint()"); PAINTSTRUCT ps; pWnd->BeginPaint(&ps); if ((m_pFilterRecord->displayPixels)(&pixels, &pixels.bounds, m_ProxyRect.top, m_ProxyRect.left, (void*)ps.hdc)) throw((char*)"DisplayPixels no go"); pWnd->EndPaint(&ps); // Do not call CDialog::OnPaint() for painting messages }
先是PSPixelMap初始化,接着用displayPixels函数显示。