M@gelearn Ответов: 4

Как справиться с несколькими случаями WM_NOTIFY ?


У меня есть 2 элемента управления представлением списка, и мне нужно отправить VM_NOTIFY для обоих из них..
Программа компилируется и запускается, но я вижу некоторые проблемы, если переключаюсь между ними.
Один из них показывает правильно, а другой показывает только первый столбец, а второй показывает несколько слов, большинство строк пусты.

LRESULT NotifyHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    LV_DISPINFOW *pLvdi = (LV_DISPINFOW *)lParam;
    ABRINFO *pAbr = (ABRINFO *)(pLvdi->item.lParam);

    if (wParam != ID_LISTVIEW)
	return 0L;

    switch(pLvdi->hdr.code)
	{
	case LVN_GETDISPINFOW:
	   switch (pLvdi->item.iSubItem)
	      {
		case 0:
		pLvdi->item.pszText = pAbr->szSymbol;
		break;
		case 1:
		pLvdi->item.pszText = pAbr->szDescription;
		break;
		default:
		break;
	}
	break;
        default:
	break;
	}
    return 0L;
}


Это уже второй случай:

LRESULT NotifyHandlerXP(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    LV_DISPINFOW *pLvdi = (LV_DISPINFOW *)lParam;
    XPINFO *pXP = (XPINFO *)(pLvdi->item.lParam);

    if(wParam != ID_LISTVIEW)
        return 0L;

    switch(pLvdi->hdr.code)
    {
    case LVN_GETDISPINFOW:
        switch(pLvdi->item.iSubItem)
        {
        case 0:
            pLvdi->item.pszText = pXP->szCharLevel;
            break;
        case 1:
            pLvdi->item.pszText = pXP->szXpNedded;
            break;
        case 2:
            pLvdi->item.pszText = pXP->szXpNeddedNextLvl;
            break;
        default:
            break;
        }
        default:
            break;
    }
    return 0L;
}


Как обращаться в MainWndProc?

LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
   static HWND hWndListView;

   switch(msg)
     {
    case WM_NOTIFY:
        {
          return (NotifyHandler(hWnd, msg, wp, lp));
          return (NotifyHandlerXP(hWnd, msg, wp, lp));
          break;
        }
     default:
        return DefWindowProcW(hWnd, msg, wp, lp);
     }
   return 0;
}


Что я уже пробовал:

Я только подумал, что, если заявление.. Я работаю над этим прямо сейчас.

HWND CreateListView(HWND hWndParent)
hWndListView = CreateListView(hWnd);

HWND CreateListViewXP(HWND hWndParentXP)
hWndListView = CreateListViewXP(hWnd);

Это 2 обработчика для обоих элементов управления представлением списка.

4 Ответов

Рейтинг:
6

M@gelearn

Ладно, думаю, я все понял. Допустим, я просто позволю этому делу уведомить вот так:

case WM_NOTIFY:
        {
            (NotifyHandlerXP(hWnd, msg, wp, lp));
            (NotifyHandler(hWnd, msg, wp, lp));
            break;
        }


Затем я изменил ID_LISTVIEWXP и NUM_ITEMLENXP для второго элемента управления listview в заголовке, и теперь кажется, что оба представления списка работают просто отлично..

Я думаю, что это не сработало, потому что у меня был один и тот же ID_LISTVIEW и один и тот же NUM_ITEMLEN для обоих элементов управления.


Richard MacCutchan

Это все еще неправильно. Вы должны проверить, к какому элементу управления относится сообщение WM_NOTIFY, и отправить информацию только этому элементу управления. Вам необходимо более подробно разобраться в обработке сообщений Windows, см. Сообщения и очереди сообщений - Win32-приложений, Майкрософт документы[^].

M@gelearn

Да Ричард я читаю об этом прямо сейчас здесь:
https://docs.microsoft.com/en-us/windows/win32/controls/wm-notify

Я знаю, что мой код работает, и я действительно знаю, что моя проблема с обработкой сообщений windows продолжается.. Я много работаю, чтобы понять их, так как я начинаю учиться Соло. Нет учителя, нет ничего просто с нуля .. Это не рекомендуется, но я уверен, что если я приеду сюда, то смогу подняться выше, потому что мне это нравится. Вот почему я иногда настаиваю на ответах, и я прошу больше информации об этом, потому что я не знаком со всем, поэтому я хочу попросить быть терпеливым со мной.. Вот и все.

Richard MacCutchan

Нет ничего плохого в обучении соло, но вам все равно нужно использовать правильную информацию. Вот ссылка на набор учебных пособий, которые могут вам помочь: учебник по Win32 API для theForger[^].

M@gelearn

Хе-хе..Уже знаю это, вот с чего я начал.. Тай очень любит..

M@gelearn

Хе-хе..Уже знаю это, вот с чего я начал.. Тай очень любит..

Рейтинг:
1

M@gelearn

Я подумывал о том, чтобы использовать только один NotifyHandler для обоих элементов управления представлением списка..


Рейтинг:
1

M@gelearn

Я подумывал о том, чтобы использовать только один NotifyHandler для обоих элементов управления представлением списка..

Я действительно использовал

case WM_NOTIFY:
        {
            (NotifyHandlerXP(hWnd, msg, wp, lp));
            (NotifyHandler(hWnd, msg, wp, lp));
            break;
        }


В противном случае список никогда не появится.

Но я понимаю, что второй элемент управления представлением списка имеет второй столбец, который не показывает элементы, как это должно быть. Поэтому я добавил еще один столбец и изменил случаи из случая 1 и случая 2

case LVN_GETDISPINFOW:
        switch(pLvdi->item.iSubItem)
        {
        case 0:
            pLvdi->item.pszText = pXP->szCharLevel;
            break;
        case 1:
            pLvdi->item.pszText = pXP->szXpNedded;
            break;
        case 2:
            pLvdi->item.pszText = pXP->szXpNeddedNextLvl;
            break;
        default:
            break;

к:

case LVN_GETDISPINFOW:
        switch(pLvdi->item.iSubItem)
        {
        case 0:
            pLvdi->item.pszText = pXP->szCharLevel;
            break;
        case 1:
            break;
        case 2:
            pLvdi->item.pszText = pXP->szXpNedded;
            break;
        case 3:
            pLvdi->item.pszText = pXP->szXpNeddedNextLvl;
            break;
        default:
            break;

к случаям 2 и 3..

Теперь список появляется, и второй coumn остается пустым.


Richard MacCutchan

Да, потому что вы игнорируете вторую колонку.

M@gelearn

Да, Ричард, теперь я проигнорировал его, потому что видел, что он никогда не показывает того, что должен показывать.. Итак, в Примере, который я написал, я полностью проигнорировал и прошел мимо.. Я просто подставляю колонку, и вторая становится 3-й, а третья-4-й..
Я проигнорировала его, потому что хотела этого.. Я сделал это, чтобы посмотреть, отображается ли текст в следующих 3-й и 4-й колонках.. и да, это было заметно, но проблема была не в этом .. Как я уже упоминал, у меня был один и тот же идентификатор и один и тот же NUM_ITEMLEN для обоих элементов управления, что не так уж и здорово .. и изменить их, чтобы иметь разные идентификаторы.. и теперь работает просто отлично..
Но все равно спасибо.. кажется, ты появляешься каждый раз, когда на дороге возникает проблема.. :)


Охх и кстати извините за последний пост и предложенный 1 балл.. Я был очень зол на другие вещи, и код прослушивался ... я ... я думаю, что принесу некоторые извинения..
Надеюсь, ты не расстроилась.. Мой плохой, как всегда ... так как я новичок, я спрашиваю налево и направо и каждый раз ожидаю конкретных ответов.. но я знаю, что каждый из нас работает и не имеет времени на то, чтобы каждая проблема была на форуме.. Так что еще раз приношу свои извинения..

Рейтинг:
0

Richard MacCutchan

Сообщение WM_NOTIFY отправляется из элемента управления, т. е. ListViews, к его родительскому окну. Затем родитель должен решить, какие действия предпринять. В том случае, когда ListView необходимо обновить вам нужно вызвать соответствующий обработчик для тот ListView- только не для них обоих. Информация, содержащаяся в WM_NOTIFY сообщение сообщает вам, какой элемент управления вызвал событие уведомления.


M@gelearn

Ну, я не знаю, как это сделать ... но звучит правильно, как вы упомянули..
Ладно, спасибо тебе за это .. Я что-нибудь придумаю..

Richard MacCutchan

Посмотрите документацию для сообщения WM_NOTIFY. Как только у вас есть дескриптор Windows для ListView, очень просто вызвать правильный обработчик.