Hi all,
I am currently trying to change the trackbar thumb by implementing a bitmap transparency, so the color and the shape of the thumb can be formed. I working with the code of AfhFM109h-sourcecode-20211231, i.e. the FilterMeister editor, the PS plugin.
While debugging in VS, I am having few issues that have to cope with. First, I am trying to understand why there is not any data allocated in hBitmapThumb, i.e. the .bmp does not load. Second, when trying to exit Photoshop after exiting FM plugin, the window of PS is totally freezed, and the last, when trying to load a control right below my custom function in this order:
%fml
CustomTrackbarThumb();
ctl(0):trackbar
Photoshop crashes.
Here's the code I am trying to implement.
HWND trackBar = NULL;
WNDPROC defWndProc = NULL;
static HBITMAP hBitmapThumb;
static BITMAP bm;
LRESULT OnWindowClose(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
PostQuitMessage(0);
return CallWindowProc(defWndProc, hwnd, message, wParam, lParam);
}
void DrawBitmapTransparent(HDC hDCDest, int nXDest, int nYDest, int nBitmapWidth, int nBitmapHeight, HBITMAP hBitmap, int nXSrc, int nYSrc, int nTransparentColor)
{
HDC hDCSrc;
HBITMAP hBitmapOld;
HDC hDCMask;
HBITMAP hBitmapMask;
HBITMAP hBitmapMaskOld;
HDC hDCMem;
HBITMAP hBitmapMem;
HBITMAP hBitmapMemOld;
int nBkColorOld;
int nTextColorOld;
BITMAP bm;
GetObject( hBitmap, sizeof( BITMAP ), &bm );
if (!nBitmapWidth) {
nBitmapWidth = bm.bmWidth;
}
if (!nBitmapHeight) {
nBitmapHeight = bm.bmHeight;
}
hDCSrc = CreateCompatibleDC( hDCDest );
hBitmapOld = (HBITMAP)SelectObject( hDCSrc, hBitmap );
hDCMask = CreateCompatibleDC( hDCDest );
hBitmapMask = CreateBitmap( nBitmapWidth, nBitmapHeight, 1, 1, 0 );
hBitmapMaskOld = (HBITMAP)SelectObject( hDCMask, hBitmapMask );
hDCMem = CreateCompatibleDC( hDCDest );
hBitmapMem = CreateCompatibleBitmap( hDCDest, nBitmapWidth, nBitmapHeight );
hBitmapMemOld = (HBITMAP)SelectObject( hDCMem, hBitmapMem );
nBkColorOld = SetBkColor( hDCSrc, nTransparentColor );
BitBlt( hDCMask, 0, 0, nBitmapWidth, nBitmapHeight, hDCSrc, nXSrc, nYSrc, SRCCOPY );
SetBkColor( hDCSrc, nBkColorOld );
nBkColorOld = SetBkColor( hDCDest, RGB(255,255,255) );
nTextColorOld = SetTextColor( hDCDest, RGB(0,0,0) );
BitBlt( hDCMem, 0, 0, nBitmapWidth, nBitmapHeight, hDCDest, nXDest, nYDest, SRCCOPY );
BitBlt( hDCMem, 0, 0, nBitmapWidth, nBitmapHeight, hDCSrc, nXSrc, nYSrc, SRCINVERT );
BitBlt( hDCMem, 0, 0, nBitmapWidth, nBitmapHeight, hDCMask, 0, 0, SRCAND );
BitBlt( hDCMem, 0, 0, nBitmapWidth, nBitmapHeight, hDCSrc, nXSrc, nYSrc, SRCINVERT );
BitBlt( hDCDest, nXDest, nYDest, nBitmapWidth, nBitmapHeight, hDCMem, 0, 0, SRCCOPY );
SetBkColor( hDCDest, nBkColorOld );
SetTextColor( hDCDest, nTextColorOld );
SelectObject( hDCMem, hBitmapMemOld );
DeleteDC( hDCMem );
DeleteObject( hBitmapMem );
SelectObject( hDCMask, hBitmapMaskOld );
DeleteDC( hDCMask );
DeleteObject( hBitmapMask );
SelectObject( hDCSrc, hBitmapOld );
DeleteDC( hDCSrc );
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch(message) {
case WM_NOTIFY:
{
LPNMHDR lpNmhdr = (LPNMHDR)lParam;
if (lpNmhdr->code == NM_CUSTOMDRAW)
{
LPNMCUSTOMDRAW lpNMCustomDraw = (LPNMCUSTOMDRAW)lParam;
if (lpNMCustomDraw->dwDrawStage == CDDS_PREPAINT) {
return CDRF_NOTIFYITEMDRAW;
}
else if (lpNMCustomDraw->dwDrawStage == CDDS_ITEMPREPAINT)
{
long nLeft = lpNMCustomDraw->rc.left;
long nTop = lpNMCustomDraw->rc.top;
long nRight = lpNMCustomDraw->rc.right;
long nBottom = lpNMCustomDraw->rc.bottom;
if (lpNMCustomDraw->dwItemSpec == TBCD_THUMB && hBitmapThumb)
{
long nWidth = nRight - nLeft;
long nHeight = nBottom - nTop;
if (nWidth - bm.bmWidth > 0)
{
nLeft += (nWidth - bm.bmWidth)/2;
nWidth = bm.bmWidth;
}
if (nHeight - bm.bmHeight > 0)
{
nTop += (nHeight - bm.bmHeight)/2;
nHeight = bm.bmHeight;
}
DrawBitmapTransparent(lpNMCustomDraw->hdc , nLeft, nTop, nWidth, nHeight, hBitmapThumb, 0, 0, RGB( 255, 0, 255 ));
return CDRF_SKIPDEFAULT;
}
}
}
}
break;
}
if (message == WM_CLOSE && hwnd == fmc.hDlg) return OnWindowClose(hwnd, message, wParam, lParam);
return CallWindowProc(defWndProc, hwnd, message, wParam, lParam);
}
INT_PTR fm_CustomTrackbarThumb(void) {
trackBar = CreateWindowEx(0, TRACKBAR_CLASS, "", WS_CHILD | TBS_HORZ | TBS_BOTTOM | WS_VISIBLE, 1, 1, 250, 20, fmc.hDlg, NULL, hDllInstance, NULL);
defWndProc = (WNDPROC)SetWindowLongPtr(fmc.hDlg, GWLP_WNDPROC, (LONG_PTR)WndProc);
hBitmapThumb = (HBITMAP)LoadImage(hDllInstance, (LPCWSTR)L"c:\\temp\\pink.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
GetObject( hBitmapThumb, sizeof( BITMAP ), &bm );
SendMessage(trackBar, TBM_SETTIPSIDE, bm.bmWidth/7, 100);
MSG message = { 0 };
while (GetMessage(&message, NULL, 0, 0))
DispatchMessage(&message);
}
There are various reasons on why I chose to edit this code, and one
of them is that in Harald Heim's VS version of FM the scripting of the
controls is having issues, they do not show in the actions panel and also when converting a layer to a SmartFilter, the compiled plugin is greyed out, i.e. disabled.
I did not choose to implement Nuklear nor ImGUI due to many issues coming between the GUI libraries and FM code itself.
Any guidance for this would be appreciated.