NO

Author Topic: Win32 ListView with Radiobuttons problem  (Read 3941 times)

kielni

  • Guest
Win32 ListView with Radiobuttons problem
« on: July 04, 2011, 02:55:43 PM »
Hello

I am "homegrown" programmer in C.

I want to have ListView Controll with Radiobuttons in my small app (Windows Mobile). I did something like that (see sall part of code):

Code: [Select]
...
static LRESULT CALLBACK TabConnectionsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
int nCount;

wchar_t keyName[MAX_PATH] = _T("");
LPWSTR pKeyName = keyName;

DWORD i, j, cbName, retCode;
HKEY hKey, hNewKey;

PAINTSTRUCT ps;
    RECT rc, newRect;
    HDC hdc, hDC; 
    HPEN hPen, hPenOld;
HFONT hFont, hHelpButtonFont, hOldFont, hOldHelpButtonFont;

LVITEM lvItem;
lvItem.mask = LVIF_TEXT|LVIF_STATE;
lvItem.state = 0;     
lvItem.stateMask = 0;

LVCOLUMN lvColumn;
lvColumn.mask = LVCF_TEXT|LVCF_WIDTH;
lvColumn.cx = 202;
lvColumn.pszText = _T("Połączenia");
lvColumn.cchTextMax = strlen("Połączenia") + 1;

INITCOMMONCONTROLSEX InitCtrlEx;
InitCtrlEx.dwSize = sizeof(INITCOMMONCONTROLSEX);
InitCtrlEx.dwICC = ICC_LISTVIEW_CLASSES;
InitCommonControlsEx(&InitCtrlEx);

    switch(uMsg)
    {

        case WM_INITDIALOG:
        {
            SHINITDLGINFO shidi;

            shidi.dwMask = SHIDIM_FLAGS;
            shidi.dwFlags = SHIDIF_SIPDOWN;
            shidi.hDlg = hDlg;

            SHInitDialog(&shidi);

hDC = GetDC(hDlg);

hOldHelpButtonFont = (HFONT)GetCurrentObject(hDC, OBJ_FONT);
hHelpButtonFont = BuildFont(hDC, hOldHelpButtonFont, 13, FW_BOLD);
SetTextColor(hDC, RGB(255, 255, 255));
SelectObject(hDC, hHelpButtonFont);

SendMessage(GetDlgItem(hDlg, IDC_BTN_HELP_CONNECTION), WM_SETFONT, (WPARAM)hHelpButtonFont, TRUE);

SelectObject(hDC, hOldHelpButtonFont);

DeleteDC(hDC);

ListView_InsertColumn(GetDlgItem(hDlg ,IDC_LIST_OF_CREATED_CONN), 0, &lvColumn);
ListView_SetExtendedListViewStyle(GetDlgItem(hDlg ,IDC_LIST_OF_CREATED_CONN), LVS_EX_CHECKBOXES|LVS_EX_FULLROWSELECT);

if(RegOpenKeyEx(HKEY_CURRENT_USER, _T("Comm\\RasBook"), 0, KEY_ENUMERATE_SUB_KEYS|KEY_EXECUTE|KEY_QUERY_VALUE, &hKey)!= ERROR_SUCCESS)
{
MessageBox(hDlg, _T("Nie udało się otworzyć klucza \"HKEY_CURRENT_USER\\Comm\\RasBook\""), _T("Błąd"), MB_ICONERROR);
return FALSE;
}
else
{
j = 0;

for(i = 0, retCode = ERROR_SUCCESS; retCode == ERROR_SUCCESS; i++)
  {
    cbName = MAX_PATH;
   
    retCode = RegEnumKeyEx(hKey, i, pKeyName, &cbName, NULL, NULL, NULL, NULL);
   
    if((retCode == (DWORD)ERROR_SUCCESS))
{

if((wcscmp(pKeyName, _T("`115200 Default")) != 0) && (wcscmp(pKeyName, _T("`19200 Default")) != 0) &&
   (wcscmp(pKeyName, _T("`38400 Default")) != 0) && (wcscmp(pKeyName, _T("`57600 Default")) != 0) &&
   (wcscmp(pKeyName, _T("`DMA Default")) != 0) && (wcscmp(pKeyName, _T("`Infrared Port")) != 0))
{

lvItem.iItem = j;
lvItem.iSubItem = 0;
lvItem.pszText  = pKeyName;
lvItem.cchTextMax = MAX_PATH;

ListView_InsertItem(GetDlgItem(hDlg ,IDC_LIST_OF_CREATED_CONN), &lvItem);

j += 1;
}
}
  }
}

if(RegCloseKey(hKey) != ERROR_SUCCESS)
{
MessageBox(hDlg, _T("Nie udało się zamknąć klucza \"HKEY_CURRENT_USER\\Comm\\RasBook\""), _T("Błąd"), MB_ICONERROR);
return FALSE;
}

return TRUE;
        }

case WM_NOTIFY:
{
            NMHDR* pnmh = (NMHDR*)lParam;

            if((pnmh->hwndFrom == GetDlgItem(hDlg, IDC_LIST_OF_CREATED_CONN)) && (pnmh->code == LVN_ITEMCHANGED))
            {
NMLISTVIEW* pnmlv = (NMLISTVIEW*)lParam;

if(pnmlv->uChanged & LVIF_STATE)
                {
if ((pnmlv->uOldState == 0) && (pnmlv->uNewState == 0))
  return FALSE;

                    if((pnmlv->uNewState & LVIS_SELECTED) && ((pnmlv->uOldState & LVIS_SELECTED) == 0))
                    {
                        ListView_SetCheckState(GetDlgItem(hDlg, IDC_LIST_OF_CREATED_CONN), pnmlv->iItem, TRUE);
ListView_SetItemState(GetDlgItem(hDlg, IDC_LIST_OF_CREATED_CONN), pnmlv->iItem, (!LVIS_SELECTED|LVIS_FOCUSED), 0x000F);
                    }

  if(ListView_GetCheckState(GetDlgItem(hDlg, IDC_LIST_OF_CREATED_CONN), pnmlv->iItem))
{
  for(nCount = 0; nCount < ListView_GetItemCount(GetDlgItem(hDlg, IDC_LIST_OF_CREATED_CONN)); nCount++)
{
    if(nCount != pnmlv->iItem)
{
    ListView_SetCheckState(GetDlgItem(hDlg, IDC_LIST_OF_CREATED_CONN), nCount, FALSE);
ListView_SetItemState(GetDlgItem(hDlg, IDC_LIST_OF_CREATED_CONN), nCount, (!LVIS_SELECTED|!LVIS_FOCUSED), 0x000F);
}

if(nCount == pnmlv->iItem)
{
ListView_SetCheckState(GetDlgItem(hDlg, IDC_LIST_OF_CREATED_CONN), nCount, TRUE);
ListView_SetItemState(GetDlgItem(hDlg, IDC_LIST_OF_CREATED_CONN), nCount, (!LVIS_SELECTED|LVIS_FOCUSED), 0x000F);
}

}
}

}

            }

            break;
        }

case WM_PAINT:
{
GetClientRect(hDlg, &rc);

hdc = BeginPaint(hDlg, &ps);

int nWidth = GetDeviceCaps(hdc, HORZRES);
const int nHeaderHeight = 18;

newRect.bottom = -4;
newRect.left = 2;
newRect.right = nWidth;
newRect.top = nHeaderHeight;

hOldFont = (HFONT)GetCurrentObject(hdc, OBJ_FONT);
hFont = BuildFont(hdc, hOldFont, 13, FW_BOLD);
SelectObject(hdc, hFont);

SetTextColor(hdc, RGB(0, 128, 255));
DrawText(hdc, _T("Krok (3/3): Wybierz połączenie"), -1, &newRect, DT_VCENTER|DT_SINGLELINE);
SelectObject(hdc, hOldFont);


hPen = CreatePen(PS_SOLID, 0, RGB(0,0,0));
hPenOld = SelectObject(hdc, hPen);

MoveToEx(hdc, 0, nHeaderHeight, NULL);
LineTo(hdc, nWidth, nHeaderHeight);

SelectObject(hdc, hPenOld);
DeleteObject(hPen);

EndPaint(hDlg, &ps);
}

        case WM_COMMAND:
            switch(GET_WM_COMMAND_ID(wParam, lParam)/*wParam*/)
            {
case IDC_BTN_OPEN_CONN_MANAGER:
{
if(!CreateProcess(_T("Windows\\remnet.exe"), NULL, NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL))
{
MessageBox(hDlg, _T("Nie udało się otworzyć menadżera połączeń"), _T("Błąd"), MB_ICONERROR);
return FALSE;
}
else
{
EnableWindow(GetDlgItem(hDlg, IDC_LIST_OF_CREATED_CONN), FALSE);
DisableCommandBarButton(hwndMainDlg, IDM_MNU_CONFIGURE);
}

return TRUE;
}

case IDC_BTN_HELP_CONNECTION:
{
if(!CreateProcess(_T("peghelp.exe"), _T("file:ConnectionsConfiguratorHelp.htm#Polaczenia"), NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL))
{
MessageBox(hDlg, _T("Nie udało się otworzyć pliku pomocy"), _T("Błąd"), MB_ICONERROR);
return FALSE;
}

return TRUE;
}

case IDC_BTN_REFRESH_CONN_LIST:
{
if(RegOpenKeyEx(HKEY_CURRENT_USER, _T("Comm\\RasBook"), 0, KEY_ENUMERATE_SUB_KEYS|KEY_EXECUTE|KEY_QUERY_VALUE, &hNewKey)!= ERROR_SUCCESS)
{
MessageBox(hDlg, _T("Nie udało się otworzyć klucza \"HKEY_CURRENT_USER\\Comm\\RasBook\""), _T("Błąd"), MB_ICONERROR);
return FALSE;
}
else
{
EnableWindow(GetDlgItem(hDlg, IDC_LIST_OF_CREATED_CONN), TRUE);

ListView_DeleteAllItems(GetDlgItem(hDlg ,IDC_LIST_OF_CREATED_CONN));

j = 0;

for(i = 0, retCode = ERROR_SUCCESS; retCode == ERROR_SUCCESS; i++)
  {
    cbName = MAX_PATH;
   
    retCode = RegEnumKeyEx(hNewKey, i, pKeyName, &cbName, NULL, NULL, NULL, NULL);

    if((retCode == (DWORD)ERROR_SUCCESS))
{
if((wcscmp(pKeyName, _T("`115200 Default")) != 0) && (wcscmp(pKeyName, _T("`19200 Default")) != 0) &&
   (wcscmp(pKeyName, _T("`38400 Default")) != 0) && (wcscmp(pKeyName, _T("`57600 Default")) != 0) &&
   (wcscmp(pKeyName, _T("`DMA Default")) != 0) && (wcscmp(pKeyName, _T("`Infrared Port")) != 0))
{

lvItem.iItem = j;
lvItem.iSubItem = 0;
lvItem.pszText  = pKeyName;
lvItem.cchTextMax = MAX_PATH;

ListView_InsertItem(GetDlgItem(hDlg ,IDC_LIST_OF_CREATED_CONN), &lvItem);

j += 1;
}
}
  }
}

if(RegCloseKey(hNewKey) != ERROR_SUCCESS)
{
MessageBox(hDlg, _T("Nie udało się zamknąć klucza \"HKEY_CURRENT_USER\\Comm\\RasBook\""), _T("Błąd"), MB_ICONERROR);
return FALSE;
}

EnableCommandBarButton(hwndMainDlg, IDM_MNU_CONFIGURE);

return TRUE;
}

                case IDOK:
                    DestroyWindow(hDlg);
//                    EndDialog(hDlg, TRUE);

                    return TRUE;
            }
            break;
    }

    return FALSE;
}
...

This is ListView Controll with Checkboxes and I used mechanism which is used in this example: http://www.codeguru.com/cpp/controls/listview/checkboxes/article.php/c1023/

I know taht there are some tips & tricks to "tune up" that technique to use/view Radiobuttons (not CheckBoxes), espetially two:
  • use custom drawing to add radio button
  • create images for checked/unchecked "radio buttons" and only change these images after mouse-click on the "radio button" area

Unfortunalty I do not know how code it. Maybe you know some steb by step example witch is placed on some website and I can't finde using Google  :(. Maybe this is very simple and a few simple lines of code do the trick.

Best regards, Grzegorz Dragan.

1. PS. Sorry for my English  ;).
2. PS. In Attachment there is full compessed project.