set transparent border to CComboBox control - winapi

I am trying to set transparent border of CComboBox control.
For other control like CEdit it is possible to do so using control properties but I am unable to find any solution for CComboBox. I want result something like shown in image.

I have found a little piece of code, I hope it help you:
// YourComboBox.h : header file
class CYourComboBox : public CComboBox
{
public:
CEdit m_edit;
CListBox m_listbox;
protected:
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
afx_msg void OnDestroy();
...
};
// YourComboBox.cpp : implementation file
HBRUSH CYourComboBox::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
if (nCtlColor == CTLCOLOR_EDIT)
{
//Edit control
if (m_edit.GetSafeHwnd() == NULL)
m_edit.SubclassWindow(pWnd->GetSafeHwnd());
}
if (nCtlColor == CTLCOLOR_LISTBOX)
{
//ListBox control
if (m_listbox.GetSafeHwnd() == NULL)
m_listbox.SubclassWindow(pWnd->GetSafeHwnd());
}
RemoveEditBorder();
HBRUSH hbr = CComboBox::OnCtlColor(pDC, pWnd, nCtlColor);
return hbr;
}
void CYourComboBox::OnDestroy()
{
if (m_edit.GetSafeHwnd() != NULL)
m_edit.UnsubclassWindow();
if (m_listbox.GetSafeHwnd() != NULL)
m_listbox.UnsubclassWindow();
CComboBox::OnDestroy();
}
void CYourComboBox::RemoveEditBorder()
{
m_edit.ModifyStyle(WS_BORDER, 0);
}

Related

CCombobox : how to set text color of Editable area text when combobox style is dropdown in win32

I am using CComboBox with style DropDown wherein user can enter data in edit area in case expected option is not available in the drop down options.
I am trying to set color of text present in Editable area using OnCtlColor but it sets color to only drop down items inserted and not the editable area.
HBRUSH CUserInfoDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
int iCtrlID;
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
iCtrlID = pWnd->GetDlgCtrlID();
if (CTLCOLOR_STATIC == nCtlColor &&
(IDC_CMB_CITY == iCtrlID)
)
{
pDC->SetTextColor(RGB(255, 0, 0));
pDC->SetBkMode(TRANSPARENT);
hbr = (HBRUSH) GetStockObject(WHITE_BRUSH);
}
if (CTLCOLOR_EDIT == nCtlColor &&
(IDC_CMB_CITY == iCtrlID)
)
{
pDC->SetTextColor(RGB(255, 0, 0));
pDC->SetBkMode(TRANSPARENT);
}
return hbr;
}
where IDC_CMB_CITY is resource ID of CComboBox control.
Found the answer with help of comments:
HBRUSH CUserInfoDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
TCHAR szText[MAX_PATH];
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
if (pWnd->m_hWnd == m_CityComboBoxInfo.hwndItem)
{
pDC->SetTextColor(RGB(255, 0, 0));
pDC->SetBkMode(TRANSPARENT);
hbr = (HBRUSH) GetStockObject(WHITE_BRUSH);
int iSel = m_Cmb_City.GetCurSel();
if (CB_ERR != iSel)
{
m_Cmb_City.GetLBText(iSel, szText);
if (0 != _tcsicmp(szText, L"some_default_text_initially_shown_on_Dropdown"))
{
pDC->SetTextColor(RGB(0, 0, 0));
}
}
}
}
where CComboBox m_Cmb_City;
and m_CityComboBoxInfo is fetched using m_Cmb_City.GetComboBoxInfo(&m_CityComboBoxInfo);
Above piece of code sets text color as initially red. When user makes selection from menu it changes text color to black

MFC: how to fix redraw properly for inherited CDialogBar?

I make an inherited class from CDialogBar.
class CMyDialogBar : public CDialogBar
{
DECLARE_DYNAMIC(CMyDialogBar)
// Implementation
public:
BOOL Create(CWnd * pParentWnd, UINT nIDTemplate, UINT nStyle, UINT nID);
BOOL Create(CWnd * pParentWnd, LPCTSTR lpszTemplateName, UINT nStyle, UINT nID);
protected:
virtual void DoDataExchange(CDataExchange* pDX) { return CDialogBar::DoDataExchange(pDX); }
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
DECLARE_MESSAGE_MAP()
};
The only big change is the function OnEraseBkgnd() because I like the background to be white.
BOOL CMyDialogBar::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
}
It works OK. However, when I move the rebar around it doesn't redraw correctly as shown in the figure below.
The source code can be downloaded here: https://138.197.210.223/test/My.zip.
You need your OnEraseBkgnd override to actually erase the background! For example, to set the entire client rectangle to white, you could do this:
BOOL CMyDialogBar::OnEraseBkgnd(CDC *pDC)
{
RECT wr; GetClientRect(&wr);
pDC->FillSolidRect(&wr, RGB(255,255,255));
return TRUE;
}
EDIT: Maybe you already have this, but also be sure to add ON_WM_ERASEBKGND to your message map:
BEGIN_MESSAGE_MAP(CMyDialogBar, CDialogBar)
// ... (other message handlers, if any) ...
ON_WM_ERASEBKGND()
END_MESSAGE_MAP()

CEdit works in ComCtrl32 Version 5.82 but not with 6.10

I want port a MFC project to the current available resources.
I develop with Microsoft Visual Studio Community.
In the older project the Windows SDK Version is 10.0.15063.0
in the new project the Windows SDK Version is 10.0.17763.0
the older project uses ComCtrl32.dll Version 5.82
the new project uses ComCtrl32.dll Version 6.10
After the update with SetWindowTextW(textp) the used CEdit control shows a black control rectangle
If I move the cursor over the control it looks as expected.
ValEdit.h :
class ValEdit : public CEdit
{
public:
ValEdit();
virtual ~ValEdit();
int ZeroMeansInactiv;
protected:
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnUpdate();
DECLARE_MESSAGE_MAP()
private:
COLORREF m_TextColor;
HBRUSH m_hBackgroundBrush;
HBRUSH m_hBackgrInactivBrush;
};
ValEdit.cpp :
ValEdit::ValEdit()
{
ZeroMeansInactiv = 1;
m_TextColor = Black;
m_hBackgroundBrush = CreateSolidBrush(RGB(255, 255, 255));
m_hBackgrInactivBrush = CreateSolidBrush(RGB(90, 90, 90));
}
ValEdit::~ValEdit()
{
}
BEGIN_MESSAGE_MAP(ValEdit, CEdit)
ON_WM_ERASEBKGND()
ON_CONTROL_REFLECT(EN_UPDATE, OnUpdate)
END_MESSAGE_MAP()
BOOL ValEdit::OnEraseBkgnd(CDC* pDC)
{
RECT rc;
this->GetClientRect(&rc);
SetMapMode(*pDC, MM_TEXT);
FillRect(*pDC, &rc, !!ZeroMeansInactiv ? m_hBackgroundBrush : m_hBackgrInactivBrush );
return TRUE;
}
void ValEdit::OnUpdate()
{
RedrawWindow();
}
Thank you for advice
Erhy
please, I need explanations!
I programmed the app step by step and found the code, which is responsible for the malfunction, that the CEdit control is not updated correctly.
HBRUSH CStyleToolkitDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
if (nCtlColor == CTLCOLOR_STATIC)
{
// We handle this message only if we have set the region
BOOL bHandled = m_bIsRgnSet;
if (bHandled)
{
HDC hDC = pDC->GetSafeHdc();
SetBkMode(hDC, TRANSPARENT);
return (HBRUSH)GetStockObject(HOLLOW_BRUSH); //causes the malfunction
}
}
return hbr;
}
If I exclude CEdit with
if (!pWnd->IsKindOf(RUNTIME_CLASS(CEdit)))
return (HBRUSH)GetStockObject(HOLLOW_BRUSH);
the CEdit Control is updated as expected.
Thank you for discussion

Creating MFC dialog to let the user choose file path

As title says, I am trying to create MFC dialog-based app to let the user select the file destination folder.
I am doing this by using CMFCShellTreeCtrl. However, somehow there is only one root item which is Desktop. I would like to see all items like My Computer, C drive etc.
Could you please tell me what's wrong and how do I fix it. Thanks.
Edit: Sorry I forgot to post my code. (Very simple dialog for browsing)
// BrowseDlg.cpp : implementation file
//
#include "stdafx.h"
#include "MFC Grab to FTP.h"
#include "BrowseDlg.h"
#include "afxdialogex.h"
// CBrowseDlg dialog
IMPLEMENT_DYNAMIC(CBrowseDlg, CDialog)
CBrowseDlg::CBrowseDlg(CWnd* pParent /*=NULL*/)
: CDialog(CBrowseDlg::IDD, pParent)
{
}
CBrowseDlg::~CBrowseDlg()
{
}
void CBrowseDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_PATH, m_PathTree);
}
BEGIN_MESSAGE_MAP(CBrowseDlg, CDialog)
ON_NOTIFY(TVN_SELCHANGED, IDC_PATH, &CBrowseDlg::OnTvnSelchangedMfcshelltree1)
ON_BN_CLICKED(IDOK, &CBrowseDlg::OnBnClickedOk)
END_MESSAGE_MAP()
// CBrowseDlg message handlers
BOOL CBrowseDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
m_PathTree.Expand(m_PathTree.GetRootItem(),TVE_EXPAND);
return TRUE; // return TRUE unless you set the focus to a control
}
void CBrowseDlg::OnTvnSelchangedMfcshelltree1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
// TODO: Add your control notification handler code here
*pResult = 0;
}
void CBrowseDlg::OnBnClickedOk()
{
m_PathTree.GetItemPath(path,m_PathTree.GetSelectedItem());
// TODO: Add your control notification handler code here
CDialog::OnOK();
}
//
#pragma once
#include "afxshelltreectrl.h"
// CBrowseDlg dialog
// header file
class CBrowseDlg : public CDialog
{
DECLARE_DYNAMIC(CBrowseDlg)
public:
CBrowseDlg(CWnd* pParent = NULL); // standard constructor
virtual ~CBrowseDlg();
// Dialog Data
enum { IDD = IDD_BROWSER };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnTvnSelchangedMfcshelltree1(NMHDR *pNMHDR, LRESULT *pResult);
CString path;
CMFCShellTreeCtrl m_PathTree;
afx_msg void OnBnClickedOk();
virtual BOOL OnInitDialog();
};
The problem is that CShellManager in not initialized. You have to do it manually. To initialize it you need to call CWinAppEx::InitShellManager() in OnInitInstance() of your CWinApp-derived class.
There is an alternative to using CMFCShellTreeCtrl, if you just want to pick a folder: IFileDialog.
This is my code for a select folder dialog (rather complicated, because I still want to support Windows XP using XFolderDialog):
HINSTANCE hEasyCTXP_DLL = NULL;
// Select Folder Dialog -- uses either CXFolderDialog or IFileDialog
// to open a folder picker dialog depending on OS version
// returns "" if Cancel was pressed or something else went wrong
// Note: This is just multi-byte code and not yet unicode compatible!
BOOL SelectFolder(LPSTR sFolder, LPCTSTR sTitle = "Choose Folder")
{
OSVERSIONINFOEX osvi;
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
osvi.dwOSVersionInfoSize = sizeof(osvi);
if (GetVersionEx((OSVERSIONINFO *)&osvi) && osvi.dwMajorVersion >= 6) // Vista or higher?
{
if (!(hEasyCTXP_DLL = LoadLibrary("XPHelper.dll")))
{
AfxMessageBox("Error opening Select Folder dialog. XPHelper.dll may not be installed properly.");
return FALSE;
}
else
{
BOOL (__cdecl *pSelectFolder)(LPSTR, LPCTSTR);
pSelectFolder = (BOOL (__cdecl *)(LPSTR, LPCTSTR))GetProcAddress(hEasyCTXP_DLL, "SelectFolder");
if (pSelectFolder)
{
return (*pSelectFolder)(sFolder, sTitle);
}
else
{
AfxMessageBox("Error opening Select Folder dialog. (SelectFolder() function entry point not found.)");
return FALSE;
}
}
}
else // XP
{
CXFolderDialog dlg(sFolder);
dlg.SetTitle(sTitle);
if (dlg.DoModal() == IDOK)
{
CString csPath = dlg.GetPath();
strcpy(sFolder, (LPCTSTR)csPath);
return TRUE;
}
else
return FALSE;
}
}
Here comes the function I provide in XPHelper.dll. This dll is delay loaded only, if Vista or later OS is used, so the main program won't fail because of missing dependencies in Windows XP:
// sFolder should be at least MAX_FILE in size!
extern "C" BOOL SelectFolder(LPSTR sFolder, LPCTSTR sTitle)
{
BOOL bRet = TRUE;
IFileDialog *pfd;
LPWSTR pwstrPath;
HRESULT hr;
if (SUCCEEDED(hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pfd))))
{
DWORD dwOptions;
hr = pfd->GetOptions(&dwOptions);
if (SUCCEEDED(hr))
hr = pfd->SetOptions(dwOptions | FOS_PICKFOLDERS); // put IFileDialog in folder mode
if (SUCCEEDED(hr))
{
WCHAR wcTitle[MAX_PATH+1];
if (MultiByteToWideChar(CP_ACP, 0, sTitle, (int)min(strlen(sTitle), MAX_PATH), wcTitle, sizeof(MAX_PATH + 1)))
{
wcTitle[min(strlen(sTitle), MAX_PATH)] = '\0';
pfd->SetTitle(wcTitle); // Set dialog title
}
char *cp = sFolder;
WCHAR wcDefaultPath[MAX_PATH+1];
IShellItem *psi;
if (MultiByteToWideChar(CP_ACP, 0, cp, (int)strlen(cp), wcDefaultPath, MAX_PATH + 1))
{
wcDefaultPath[strlen(cp)] = '\0';
if (SUCCEEDED(::SHCreateItemFromParsingName(wcDefaultPath, NULL, IID_PPV_ARGS(&psi))))
{
hr = pfd->SetFileName(wcDefaultPath);
hr = pfd->SetFolder(psi);
psi->Release();
}
}
}
if (SUCCEEDED(hr))
hr = pfd->Show(AfxGetMainWnd()->GetSafeHwnd());
if (SUCCEEDED(hr))
{
IShellItem *psi;
if (SUCCEEDED(pfd->GetResult(&psi)))
{
if(SUCCEEDED(psi->GetDisplayName(SIGDN_FILESYSPATH, &pwstrPath)))
{
int nSize = (int)wcslen(pwstrPath);
WideCharToMultiByte(CP_ACP, 0, pwstrPath, nSize, sFolder, MAX_PATH+1, NULL, NULL);
sFolder[nSize] = '\0';
::CoTaskMemFree(pwstrPath);
}
else
{
AfxMessageBox("IShellItem::GetDisplayName() failed.");
bRet = FALSE;
}
psi->Release();
}
else
{
AfxMessageBox("IFileDialog failed.");
bRet = FALSE;
}
}
pfd->Release();
}
if(!SUCCEEDED(hr))
bRet = FALSE;
return bRet;
}

Owner draw CSliderCtrl using MFC: why my program-created slider has an incorrect channel rect?

I am trying to implement an owner draw CSliderCtrl. It seems drawing is fine, however the mouse to change the thumb position is very weird. It is limited only in a very small rect. And I found that the rect by GetChannelRect is much smaller than the rect I used to create the slider control.
Below is .h file:
#if !defined(AFX_OWNDRAWSLIDER_H__82981708_4CBC_4D1E_8982_504E99BE489D__INCLUDED_)
#define AFX_OWNDRAWSLIDER_H__82981708_4CBC_4D1E_8982_504E99BE489D__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// OwnDrawSlider.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// COwnDrawSlider window
class COwnDrawSlider : public CSliderCtrl
{
// Construction
public:
COwnDrawSlider();
// Attributes
public:
CBrush black_brush;
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(COwnDrawSlider)
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~COwnDrawSlider();
// Generated message map functions
protected:
//{{AFX_MSG(COwnDrawSlider)
afx_msg void OnPaint();
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_OWNDRAWSLIDER_H__82981708_4CBC_4D1E_8982_504E99BE489D__INCLUDED_)
Here is the OwnDrawSlider class cpp:
// OwnDrawSlider.cpp : implementation file
//
#include "stdafx.h"
#include "OwnDrawSlider.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// COwnDrawSlider
COwnDrawSlider::COwnDrawSlider()
{
black_brush.CreateSolidBrush(RGB(0,0,0));
}
COwnDrawSlider::~COwnDrawSlider()
{
}
BEGIN_MESSAGE_MAP(COwnDrawSlider, CSliderCtrl)
//{{AFX_MSG_MAP(COwnDrawSlider)
ON_WM_PAINT()
ON_WM_CTLCOLOR()
ON_WM_ERASEBKGND()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// COwnDrawSlider message handlers
void COwnDrawSlider::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
CRect channelRect,thumbRect;
GetChannelRect(&channelRect);
GetThumbRect(&thumbRect);
GetClientRect(&channelRect);
thumbRect=channelRect;
channelRect.top+=5;
channelRect.bottom-=5;
int mid=(channelRect.top+channelRect.bottom)/2;
int w=channelRect.right-channelRect.left;
int pos=GetPos();
int minVal,maxVal;
GetRange(minVal,maxVal);
thumbRect.left=(pos-minVal)*w/(maxVal-minVal);
thumbRect.right=thumbRect.left+(channelRect.right-channelRect.left)*0.025f;
thumbRect.top+=12;
thumbRect.bottom-=12;
//draw the channel
//CBrush whiteBrush(RGB(255,255,255));
//dc.SelectObject(whiteBrush);
//dc.FrameRect(&channelRect,&whiteBrush);
//draw the thumb
CBrush yellowBrush(RGB(255,255,0));
dc.SelectObject(yellowBrush);
dc.Ellipse(&thumbRect);
CFont myFont;
myFont.CreatePointFont(96,"Tahoma");
dc.SetBkColor(RGB(0,0,0));
dc.SetTextColor(RGB(255,255,255));
dc.SelectObject(&myFont);
char msg[128];
sprintf(msg,"%d",pos);
CRect msgRect=thumbRect;
msgRect.top=thumbRect.bottom;
msgRect.bottom=msgRect.top+16;
int mid0=(thumbRect.left+thumbRect.right)/2;
msgRect.left=mid0-6*strlen(msg);
msgRect.right=mid0+6*strlen(msg);
dc.DrawText(msg,strlen(msg),&msgRect,DT_CENTER);
sprintf(msg,"%d",minVal);
msgRect.left=channelRect.left;
msgRect.right=channelRect.left+12*strlen(msg);
dc.DrawText(msg,strlen(msg),&msgRect,DT_LEFT);
sprintf(msg,"%d",maxVal);
msgRect.left=channelRect.right-12*strlen(msg);
msgRect.right=channelRect.right;
dc.DrawText(msg,strlen(msg),&msgRect,DT_RIGHT);
//draw the axis
CPen yellowPen(PS_SOLID,3,RGB(255,255,255));
dc.SelectObject(yellowPen);
dc.MoveTo(channelRect.left,mid);
dc.LineTo(channelRect.right,mid);
dc.MoveTo(channelRect.left,channelRect.top+12);
dc.LineTo(channelRect.left,channelRect.bottom-12);
dc.MoveTo(channelRect.right,channelRect.top+12);
dc.LineTo(channelRect.right,channelRect.bottom-12);
CPen thinPen(PS_SOLID,1,RGB(255,255,0));
dc.SelectObject(thinPen);
int numTick=GetNumTics();
DWORD* ptick=GetTicArray();
float pixelPerTick=w*1.0/numTick;
for(int i=0;i<numTick;i++)
{
dc.MoveTo((ptick[i])*pixelPerTick+channelRect.left,mid-3);
dc.LineTo((ptick[i])*pixelPerTick+channelRect.left,mid+3);
}
// Do not call CSliderCtrl::OnPaint() for painting messages
}
HBRUSH COwnDrawSlider::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CSliderCtrl::OnCtlColor(pDC, pWnd, nCtlColor);
// TODO: Change any attributes of the DC here
// TODO: Return a different brush if the default is not desired
return black_brush;
}
BOOL COwnDrawSlider::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
RECT client;
GetClientRect(&client);
//COLORREF color=pDC->GetBkColor();
COLORREF color=::GetSysColor(COLOR_WINDOW);
//FillRect(pDC->m_hDC,&client,::GetStockObject(GRAY_BRUSH));
//pDC->FillSolidRect(&client,color);
pDC->FillSolidRect(&client,RGB(0,0,0));
return true;//do not call OnEraseBkgrnd, it will fill it white
//return CSliderCtrl::OnEraseBkgnd(pDC);
}
Create the slider using program (no resource associated with it):
pFrameSlider=new COwnDrawSlider();
pFrameSlider->Create(WS_CHILD|WS_VISIBLE|BS_OWNERDRAW|TBS_HORZ|TBS_AUTOTICKS,rButton,this,ID_FRAME_SLIDER);
//pFrameSlider->SizeToContent();
pFrameSlider->SetTicFreq(50);
pFrameSlider->ShowWindow(SW_SHOW);
In the parent window, the NM_RELEASECAPTURE is trapped. When created, the rect=[9,57,384,822]. The rect obtained by the GetChannelRect is [19,23, 8, 40]. and the mouse operation is limited in this rect.
My question is: why the two rect are so different? How can I change the channel rect by program (without any resource associated with it)?

Resources