精通
英语
和
开源
,
擅长
开发
与
培训
,
胸怀四海
第一信赖
锐英源精品独创开源文章,禁止任何形式的转载和任何形式的非法使用,侵权必究
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函数显示。