Модераторы: feodorv, GremlinProg, xvr, Fixin

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как изменить цвет фона или текста, отдельного элемента в List View, WinAPI 
:(
    Опции темы
S.A.G.
Дата 29.3.2008, 21:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


не эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1339
Регистрация: 20.7.2006
Где: in ad equate

Репутация: нет
Всего: 19



Читаю MSDN и никак немогу врубиться как это сделать. Что нужно делать, перехватив сообщение WM_NOTIFY?


--------------------
Вот она задачка: спасти себя от себя самого © Cube
Sometimes good people do evil things © A Simple Plan
PM   Вверх
korian
Дата 29.3.2008, 22:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 4
Всего: 17



PM   Вверх
S.A.G.
Дата 30.3.2008, 11:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


не эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1339
Регистрация: 20.7.2006
Где: in ad equate

Репутация: нет
Всего: 19



korian, Я как раз читаю это и много чего другого, но разобраться пока немогу. Я так понимаю, что никак не изменишь цвет или фон ячейки просто изменив соотв. значения в передаваемых структурах в обработчик WM_NOTIFY? Т.е. выходит, что изменятся только локальные параметры обработчика. Может отослать WM_NOTIFY в нужный момент с обновленными структурами в качестве параметров? Иного выхода пока невижу.


--------------------
Вот она задачка: спасти себя от себя самого © Cube
Sometimes good people do evil things © A Simple Plan
PM   Вверх
korian
Дата 30.3.2008, 12:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 4
Всего: 17



http://msdn2.microsoft.com/en-us/library/b...817(VS.85).aspx
пример изменения шрифта и его clrTextBk и clrText
HDC есть, так что, менять можно все, что можно менять для HDC.
некоторые операции делаются просто (как с шрифтом - установка нового шрифта, и return CDRF_NEWFONT)
а другие изменения делаем при PREPAINT и возвращаем исходное состояние HDC в POSTPAINT

PM   Вверх
S.A.G.
Дата 30.3.2008, 12:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


не эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1339
Регистрация: 20.7.2006
Где: in ad equate

Репутация: нет
Всего: 19



korian, спасибо за наводку. Оказывается, есть технология Custom Draw. Сейчас почитаю про нее в своей MSDN.


--------------------
Вот она задачка: спасти себя от себя самого © Cube
Sometimes good people do evil things © A Simple Plan
PM   Вверх
S.A.G.
Дата 30.3.2008, 17:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


не эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1339
Регистрация: 20.7.2006
Где: in ad equate

Репутация: нет
Всего: 19



Проблема, однако, не решена. Вот пример из MSDN:
Код
LPNMLISTVIEW  pnm    = (LPNMLISTVIEW)lParam;

switch (pnm->hdr.code){
...
case NM_CUSTOMDRAW:

    LPNMLVCUSTOMDRAW  lplvcd = (LPNMLVCUSTOMDRAW)lParam;

    switch(lplvcd->nmcd.dwDrawStage) {

    case CDDS_PREPAINT :
        return CDRF_NOTIFYITEMDRAW;

    case CDDS_ITEMPREPAINT:
        SelectObject(lplvcd->nmcd.hdc,
                     GetFontForItem(lplvcd->nmcd.dwItemSpec,
                                    lplvcd->nmcd.lItemlParam) );
        lplvcd->clrText = GetColorForItem(lplvcd->nmcd.dwItemSpec,
                                          lplvcd->nmcd.lItemlParam);
        lplvcd->clrTextBk = GetBkColorForItem(lplvcd->nmcd.dwItemSpec,
                                              lplvcd->nmcd.lItemlParam);

/* At this point, you can change the background colors for the item
and any subitems and return CDRF_NEWFONT. If the list-view control
is in report mode, you can simply return CDRF_NOTIFYSUBITEMREDRAW
to customize the item's subitems individually */
        ...

        return CDRF_NEWFONT;
    //  or return CDRF_NOTIFYSUBITEMREDRAW;

    case CDDS_SUBITEM | CDDS_ITEMPREPAINT:
        SelectObject(lplvcd->nmcd.hdc,
                     GetFontForSubItem(lplvcd->nmcd.dwItemSpec,
                                       lplvcd->nmcd.lItemlParam,
                                       lplvcd->iSubItem));
        lplvcd->clrText = GetColorForSubItem(lplvcd->nmcd.dwItemSpec,
                                             lplvcd->nmcd.lItemlParam,
                                             lplvcd->iSubItem));
        lplvcd->clrTextBk = GetBkColorForSubItem(lplvcd->nmcd.dwItemSpec,
                                                 lplvcd->nmcd.lItemlParam,
                                                 lplvcd->iSubItem));

/* This notification is received only if you are in report mode and
returned CDRF_NOTIFYSUBITEMREDRAW in the previous step. At
this point, you can change the background colors for the
subitem and return CDRF_NEWFONT.*/
        ...
        return CDRF_NEWFONT;    
    }
...
}


Что делает функция GetFontForSubItem()? Кстати, в MSDN ее ненайти. И негде в студии ее тоже нет, гы гы гы. Вот она - забота о разработчиках от MS. Ладно, книжики есть корявые, но такого я не ожидал. Везде в примерах не рабочие коды, а постоянные сокращения. И еще на английском языке. Особенно любопытны ее параметры:

1. dwItemSpec - The item number. What is contained in this member will depend on the type of control that is sending the notification. See the NM_CUSTOMDRAW notification reference for the specific control to determine what, if anything, is contained in this member.

2. lItemlParam - Application-defined item data

3. iSubItem - в nmc вообще нету такого элемента.

Ну просто сказка - как же в этом разобраться?

Впрочем, понятно, что предпринимается попытка загрузить в контекст контрола необходимый цвет, шрифт и фон. Хотя рекомендуют они делать так(что тоже неработает):

Цитата
To change text colors for all controls that support custom draw except for the list view and tree view, simply set the desired text and background colors in the device context supplied in the custom draw notification structure with the SetTextColor and SetBkColor functions. To modify the text colors in the list view or tree view, you need to place the desired color values in the clrText and clrTextBk members of the NMLVCUSTOMDRAW or NMTVCUSTOMDRAW structure.


Предлагают пользоваться вторым вариантом, а в примере криво показали второй. А - ну да, цвет и фон просто записывают в локальные параметры, а шрифт заносят в контекст.


Это сообщение отредактировал(а) S.A.G. - 30.3.2008, 17:43


--------------------
Вот она задачка: спасти себя от себя самого © Cube
Sometimes good people do evil things © A Simple Plan
PM   Вверх
korian
Дата 30.3.2008, 17:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 4
Всего: 17



GetFontForSubItem - это Application Defined функция =)
короче ее вы должны написать сами...
она должна возвращает нужный шрифт в зависимости от того, какая ячейка в данный момент рисуется.
все ее параметры описывают ячейку.

Добавлено через 2 минуты и 1 секунду
Цитата(S.A.G. @  30.3.2008,  16:25 Найти цитируемый пост)
Предлагают пользоваться вторым вариантом, а в примере криво показали второй.

в цитате ясно сказано "except for the list view and tree view".

Это сообщение отредактировал(а) korian - 30.3.2008, 17:35
PM   Вверх
S.A.G.
Дата 30.3.2008, 17:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


не эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1339
Регистрация: 20.7.2006
Где: in ad equate

Репутация: нет
Всего: 19



Вот код моего обработчика:
Код

BOOL DlgOnNotify(HWND hwnd, INT, NMHDR * pnmh)
{    
    if ((pnmh->hwndFrom == hWndLV1) && (pnmh->code == NM_CUSTOMDRAW))
    {
        NMLVCUSTOMDRAW * lpNMCustomDraw = lpNMCustomDraw = (NMLVCUSTOMDRAW *)pnmh;
        DWORD dwDrawStage = lpNMCustomDraw->nmcd.dwDrawStage;
        HDC hdc = lpNMCustomDraw->nmcd.hdc;
            switch(dwDrawStage)
            {
                case CDDS_PREPAINT:        return CDRF_NOTIFYITEMDRAW;
                case CDDS_ITEMPREPAINT: SetTextColor(hdc, RGB(255, 0, 0));
                                        return CDRF_NEWFONT;
            }
    }
}

Он компилируется. Где ошибка? Цель - все итемы должны быть красными. Если выходит не то, то что? Разъясните, пожалуйста.

Добавлено @ 17:39
Кстати, по поводу
Цитата

To modify the text colors in the list view or tree view, you need to place the desired color values in the clrText and clrTextBk members of the NMLVCUSTOMDRAW or NMTVCUSTOMDRAW structure.

Просто place??? - я сделал просто place в локальный параметр, но что дальше? - Система помимо return еще проверяет, что я записал в локальный параметр обработчика???

Добавлено @ 17:47
Цитата(korian @  30.3.2008,  17:34 Найти цитируемый пост)
в цитате ясно сказано "except for the list view and tree view".

Ага, ну так я же "place", а оно неработает.

Это сообщение отредактировал(а) S.A.G. - 30.3.2008, 17:55


--------------------
Вот она задачка: спасти себя от себя самого © Cube
Sometimes good people do evil things © A Simple Plan
PM   Вверх
korian
Дата 30.3.2008, 17:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 4
Всего: 17



Цитата(S.A.G. @  30.3.2008,  16:37 Найти цитируемый пост)
Система помимо return еще проверяет что я записал в локальный параметр обработчика??? 

параметр не локальный, вы получаете ссылку на него от куда-то, а точнее из функции-рисовальщика ячейки.
Код

BOOL DlgOnNotify(HWND hwnd, INT, NMHDR * pnmh)
{    
    if ((pnmh->hwndFrom == hWndLV1) && (pnmh->code == NM_CUSTOMDRAW))
    {
        NMLVCUSTOMDRAW * lpNMCustomDraw = lpNMCustomDraw = (NMLVCUSTOMDRAW *)pnmh;
        DWORD dwDrawStage = lpNMCustomDraw->nmcd.dwDrawStage;
//        HDC hdc = lpNMCustomDraw->nmcd.hdc;
            switch(dwDrawStage)
            {
                case CDDS_PREPAINT:        return CDRF_NOTIFYITEMDRAW;
                case CDDS_ITEMPREPAINT: lpNMCustomDraw->clrText = RGB(255, 0, 0);
                                        return CDRF_NEWFONT;
            }
    }
}

вроде так
PM   Вверх
S.A.G.
Дата 30.3.2008, 17:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


не эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1339
Регистрация: 20.7.2006
Где: in ad equate

Репутация: нет
Всего: 19



Ну так вы же не поменяли ничего? Просто закомментировали объявление hdc?

Добавлено через 1 минуту и 40 секунд
Цитата(korian @  30.3.2008,  17:52 Найти цитируемый пост)
параметр не локальный, вы получаете ссылку на него от куда-то, а точнее из функции-рисовальщика ячейки.

Это прояснили, но все по прежнему неработает.


--------------------
Вот она задачка: спасти себя от себя самого © Cube
Sometimes good people do evil things © A Simple Plan
PM   Вверх
korian
Дата 30.3.2008, 17:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 4
Всего: 17



Цитата(S.A.G. @  30.3.2008,  16:54 Найти цитируемый пост)
Ну так вы же не поменяли ничего?

поменял
case CDDS_ITEMPREPAINT: SetTextColor(hdc, RGB(255, 0, 0));
case CDDS_ITEMPREPAINT: lpNMCustomDraw->clrText = RGB(255, 0, 0);


Это сообщение отредактировал(а) korian - 30.3.2008, 18:02
PM   Вверх
S.A.G.
Дата 30.3.2008, 18:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


не эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1339
Регистрация: 20.7.2006
Где: in ad equate

Репутация: нет
Всего: 19



Цитата(korian @  30.3.2008,  17:58 Найти цитируемый пост)
поменял

Я после того как написал предыдущее сообщение (незная о вашей замене) сделал так и не заработало. И раньше делал - не зарабатывало. Чушь какая-то..

Добавлено через 11 минут и 16 секунд
Может еще у кого-нибудь появяться какие-нибудь мысли?


--------------------
Вот она задачка: спасти себя от себя самого © Cube
Sometimes good people do evil things © A Simple Plan
PM   Вверх
korian
Дата 31.3.2008, 09:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 4
Всего: 17



Цитата(S.A.G. @  30.3.2008,  17:14 Найти цитируемый пост)
Я после того как написал предыдущее сообщение (незная о вашей замене) сделал так и не заработало. И раньше делал - не зарабатывало. Чушь какая-то..

код написанный выше - рабочий код, если DlgOnNotify вызывается при WM_NOTIFY парента, а hWndLV1 - HWND ListView
там правда хз, нафига такое написано:
NMLVCUSTOMDRAW * lpNMCustomDraw = lpNMCustomDraw = (NMLVCUSTOMDRAW *)pnmh;
но оно все равно работает.

как конкретно оно у вас не работает? и давайте тогда уж побольше кода...
PM   Вверх
S.A.G.
Дата 31.3.2008, 11:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


не эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1339
Регистрация: 20.7.2006
Где: in ad equate

Репутация: нет
Всего: 19



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


--------------------
Вот она задачка: спасти себя от себя самого © Cube
Sometimes good people do evil things © A Simple Plan
PM   Вверх
S.A.G.
Дата 31.3.2008, 13:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


не эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1339
Регистрация: 20.7.2006
Где: in ad equate

Репутация: нет
Всего: 19



Оно почему-то не переходит на кейс CDDS_ITEMPREPAINT. Ставлю брейк - запускается сразу окошко -> программа и не доходит до изменения цвета для каждого итем-а. Почитал ОЧЕНЬ вдумчиво документацию в MSDN про Custom Draw. Оно должно, поидее, и все subitem-ы рисовать красным, но у меня попрежнему все черное. Может я неправильно описал стиль диалога (у меня прога на основе диалога). Вот описание:

Код

IDD_DIALOG1 DIALOGEX 0, 0, 649, 295
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Метод Гомори"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
    CONTROL         "1",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,2,27,647,126,WS_EX_LEFTSCROLLBAR
    CONTROL         "2",IDC_LIST2,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | LVS_NOCOLUMNHEADER | WS_BORDER | WS_TABSTOP,86,2,563,25
END


У меня два List-а. Первый тот что hWndLV1


--------------------
Вот она задачка: спасти себя от себя самого © Cube
Sometimes good people do evil things © A Simple Plan
PM   Вверх
S.A.G.
Дата 31.3.2008, 13:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


не эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1339
Регистрация: 20.7.2006
Где: in ad equate

Репутация: нет
Всего: 19



И еще. Начинаю подозревать версию моей comctl32.dll во всех грехах. Может она имеет значение. У меня эта длл в 3 экземплярах. В MSDN читал что по умолчанию грузится 5 версия. У меня версия ФАЙЛА 5.8.., а в ВЕРСИИ ПРОДУКТА написано 6.. Я имею ввиду ту длл, что находится в system32

Это сообщение отредактировал(а) S.A.G. - 31.3.2008, 13:41


--------------------
Вот она задачка: спасти себя от себя самого © Cube
Sometimes good people do evil things © A Simple Plan
PM   Вверх
korian
Дата 31.3.2008, 14:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 4
Всего: 17



Цитата(S.A.G. @  31.3.2008,  12:41 Найти цитируемый пост)
Начинаю подозревать версию моей comctl32.dll во всех грехах

CUSTOM_DRAW еще с версии Win3.1 вроде бы (Win95 точно) работает
причина не в этом
покажите где и как вы вызываете функцию DlgOnNotify

PM   Вверх
S.A.G.
Дата 31.3.2008, 14:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


не эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1339
Регистрация: 20.7.2006
Где: in ad equate

Репутация: нет
Всего: 19



Текстом таблицу заполняю в обработчике инициализации диалога, в отдельной функции. Обработчик WM_NOTIFY ессно выполняется после.

Выкладываю весь код:

Код

#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include <stdlib.h>
#include "resource.h"

BOOL CALLBACK DlgProc(HWND, UINT, WPARAM, LPARAM);
void DlgOnCommand(HWND, int, HWND, UINT);
BOOL DlgOnInitDialog(HWND, HWND, LPARAM);
BOOL DlgOnNotify(HWND, INT, NMHDR *);
//мои функции
void CreateTable(HWND hwnd);
void PreFillTable();

#define MVALUE 10000

HINSTANCE hInstance;
HWND hWndLV1, hWndLV2;
LVITEM lvi;
double Cbas[8]; //базисное решение
double WholeFuncCoeff[20]; //коэффициенты целевой функции
double Matrix[9][21]; //симплекс-матрица
char szText[256];
int iColNum;
int iRowNum;

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, int)
{
    INITCOMMONCONTROLSEX icex;
    
    hInstance = hInst; //сохраняем дескриптор приложения
    icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
    icex.dwICC  = ICC_LISTVIEW_CLASSES;
    InitCommonControlsEx(&icex); //регистрируем классы для List View
    DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DlgProc);
    return 0;
}
BOOL CALLBACK DlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
        HANDLE_MSG(hwnd, WM_INITDIALOG, DlgOnInitDialog);
        HANDLE_MSG(hwnd, WM_COMMAND, DlgOnCommand);
        HANDLE_MSG(hwnd, WM_NOTIFY, DlgOnNotify);
        default: return FALSE;
    }
}
BOOL DlgOnInitDialog(HWND hwnd, HWND, LPARAM)
{
    CreateTable(hwnd);
    PreFillTable();
    return TRUE;
}
void DlgOnCommand(HWND hwnd, int id, HWND, UINT)
{
    switch(id)
    {
        case IDOK:
        case IDCANCEL: EndDialog(hwnd, 0);
    }
}
void CreateTable(HWND hwnd)
{
    LVCOLUMN lvc;
    int iCol, iRow;
    int iCorr = 0;
    
    //определяем дескриптор первого List Control-а
    hWndLV1 = FindWindowEx(hwnd, NULL, WC_LISTVIEW, "1");
    //загружаем количество колонок
    LoadString(hInstance, 0, szText, sizeof(szText)/sizeof(szText[0]));
    iColNum = atoi(szText);
    //обнуляем структуру для колонок
    ZeroMemory(&lvc, sizeof(lvc));
    //устанавливаем общие характеристики всех колонок
    lvc.mask = LVCF_WIDTH | LVCF_TEXT;
    lvc.cx = 42;
    //формируем колонки таблицы
        for (iCol = 0; iCol < iColNum; iCol++)
        {
            LoadString(hInstance, iCol + 2, szText, sizeof(szText)/sizeof(szText[0]));
            lvc.pszText = szText;
            ListView_InsertColumn(hWndLV1, iCol, &lvc);
        }
    //загружаем количество строк
    LoadString(hInstance, 1, szText, sizeof(szText)/sizeof(szText[0]));
    iRowNum = atoi(szText);
    //обнуляем структуру для строк
    ZeroMemory(&lvi, sizeof(lvi));
    lvi.mask = LVIF_TEXT;
    //формируем крайний левый столбец
        for(iRow = 0; iRow < 8; iRow++)
        {
            lvi.iItem = iRow;
                if (iRow < 4)
                    LoadString(hInstance, iRow + 13, szText, sizeof(szText)/sizeof(szText[0]));
                else
                {
                    LoadString(hInstance, iRow + 14 + iCorr, szText, sizeof(szText)/sizeof(szText[0]));
                    iCorr++;
                }
            lvi.pszText = szText;
            ListView_InsertItem(hWndLV1, &lvi);
        }
    //вставляем "пустой" элемент
    lvi.iItem = iRow;
    lvi.pszText = "";
    ListView_InsertItem(hWndLV1, &lvi);
    //теперь нам нужен другой List Control
    hWndLV2 = FindWindowEx(hwnd, NULL, WC_LISTVIEW, "2");
    //Обнуляем структуру для колонок
    ZeroMemory(&lvc, sizeof(lvc));
    //устанавливаем общие характеристики всех колонок
    lvc.mask = LVCF_WIDTH;
    lvc.cx = 42;
        for (iCol = 0; iCol < iColNum - 3; iCol++)
            ListView_InsertColumn(hWndLV2, iCol, &lvc);
}
void PreFillTable()
{
    int i;
    int j = 0;
    char * szMvalue;
    
    //заполняем структуры данных
    ZeroMemory(Cbas, sizeof(Cbas));
        for(i = 4; i < 8; i++)
            Cbas[i] = MVALUE;
    ZeroMemory(WholeFuncCoeff, sizeof(WholeFuncCoeff));
        for (i = 13; i < 20; i++)
        {
                if ((i % 2) == 0)
                    continue;
            WholeFuncCoeff[i] = MVALUE;
        }
    ZeroMemory(Matrix, sizeof(Matrix));
        for(i = 0; i < 4; i++)
        {
            Matrix[i][i * 2 + 1] = 1;
            Matrix[i][i * 2 + 2] = 1;
            Matrix[i][i + 9] = 1;
        }
            for(i = 4; i < 8; i++)
            {
                j++;
                Matrix[i][i + j + 8] = -1;
                Matrix[i][i + j + 9] = 1;
            }
    Matrix[4][1] = 1; Matrix[4][5] = 1;
    Matrix[5][3] = 1; Matrix[5][7] = 1;
    Matrix[6][2] = 1; Matrix[6][6] = 1;
    Matrix[7][4] = 1; Matrix[7][8] = 1;
    //заполняем таблицы начальными даными
    //вставка Сбаз
    ZeroMemory(&lvi, sizeof(lvi));
    lvi.mask = LVIF_TEXT;
    lvi.iSubItem = 1;
    lvi.pszText = "";
        for(i = 0; i < 4; i++)
        {    
            lvi.iItem = i;
            ListView_SetItem(hWndLV1, &lvi);
        };
    szMvalue = _itoa(MVALUE, szText, 10);
    lvi.pszText = szMvalue;
        for(i = 4; i < 8; i++)
        {    
            lvi.iItem = i;
            ListView_SetItem(hWndLV1, &lvi);
        };
    //вставка "пустого" subitem-а
    lvi.iItem = i;
    lvi.pszText = "";
    ListView_SetItem(hWndLV1, &lvi);
    //вставка коэффициентов при ЦФ
    //вставка первого item-а
    lvi.iItem = 0;
    lvi.iSubItem = 0;
    ListView_InsertItem(hWndLV2, &lvi);
        for(i = 1; i < iColNum - 3; i++)
        {
            lvi.iSubItem = i;
                if (WholeFuncCoeff[i] == 0)
                    lvi.pszText = "";
                else
                    lvi.pszText = szMvalue;
            ListView_SetItem(hWndLV2, &lvi);
        };
    //заполнение симплекс-матрицы
    for(i = 0; i < 9; i++)
        for(j = 0; j < 21; j++)
        {
            lvi.iItem = i;
            lvi.iSubItem = j + 2;
                if(Matrix[i][j] == 0)
                    lvi.pszText = "";
                else
                    lvi.pszText = _itoa((int)Matrix[i][j], szText, 10);
            ListView_SetItem(hWndLV1, &lvi);
        };
}
BOOL DlgOnNotify(HWND hwnd, INT, NMHDR * pnmh)
{
    if ((pnmh->hwndFrom == hWndLV1) && (pnmh->code == NM_CUSTOMDRAW))
    {
        NMLVCUSTOMDRAW * lpNMCustomDraw = (NMLVCUSTOMDRAW *)pnmh;
        DWORD dwDrawStage = lpNMCustomDraw->nmcd.dwDrawStage;
        HDC hdc = lpNMCustomDraw->nmcd.hdc;
            switch (dwDrawStage)
            {
                case CDDS_PREPAINT    : return CDRF_NOTIFYITEMDRAW;                                    
                case CDDS_ITEMPREPAINT: ((NMLVCUSTOMDRAW *)pnmh)->clrText = RGB(255, 0, 0); //СЮДА ПРОГРАММА НЕ ДОХОДИТ
                                        ((NMLVCUSTOMDRAW *)pnmh)->clrTextBk = RGB(255, 255, 255);
                                        return CDRF_NEWFONT;
            }
    }
}

Код

// Microsoft Visual C++ generated resource script.
//
#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"

/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS

/////////////////////////////////////////////////////////////////////////////
// Russian resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
#ifdef _WIN32
LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
#pragma code_page(1251)
#endif //_WIN32

#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//

1 TEXTINCLUDE 
BEGIN
    "resource.h\0"
END

2 TEXTINCLUDE 
BEGIN
    "#include ""afxres.h""\r\n"
    "\0"
END

3 TEXTINCLUDE 
BEGIN
    "\r\n"
    "\0"
END

#endif    // APSTUDIO_INVOKED

#endif    // Russian resources
/////////////////////////////////////////////////////////////////////////////


/////////////////////////////////////////////////////////////////////////////
// Ukrainian resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_UKR)
#ifdef _WIN32
LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT
#pragma code_page(1251)
#endif //_WIN32

/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//

IDD_DIALOG1 DIALOGEX 0, 0, 649, 295
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Метод Гомори"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
    CONTROL         "1",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,2,27,647,126,WS_EX_LEFTSCROLLBAR
    CONTROL         "2",IDC_LIST2,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | LVS_NOCOLUMNHEADER | WS_BORDER | WS_TABSTOP,86,2,563,25
END


/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//

#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO 
BEGIN
    IDD_DIALOG1, DIALOG
    BEGIN
        LEFTMARGIN, 2
        RIGHTMARGIN, 647
        TOPMARGIN, 2
        BOTTOMMARGIN, 293
    END
END
#endif    // APSTUDIO_INVOKED


/////////////////////////////////////////////////////////////////////////////
//
// String Table
//

STRINGTABLE 
BEGIN
    IDS_STRING0             "23"
    IDS_STRING1             "9"
    IDS_STRING2             "Базис"
    IDS_STRING3             "Сбаз"
    IDS_STRING4             "БР"
    IDS_STRING5             "А1"
    IDS_STRING6             "А2"
    IDS_STRING7             "А3"
    IDS_STRING8             "А4"
    IDS_STRING9             "А5"
    IDS_STRING10            "А6"
    IDS_STRING11            "А7"
    IDS_STRING12            "А8"
    IDS_STRING13            "А9"
    IDS_STRING14            "А10"
    IDS_STRING15            "А11"
END

STRINGTABLE 
BEGIN
    IDS_STRING16            "А12"
    IDS_STRING17            "А13"
    IDS_STRING18            "А14"
    IDS_STRING19            "А15"
    IDS_STRING20            "А16"
    IDS_STRING21            "А17"
    IDS_STRING22            "А18"
    IDS_STRING23            "А19"
    IDS_STRING24            "А20"
END

#endif    // Ukrainian resources
/////////////////////////////////////////////////////////////////////////////



#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//


/////////////////////////////////////////////////////////////////////////////
#endif    // not APSTUDIO_INVOKED


Для чего нужен Custom Draw. Хочу один столбец сделать красным, другой - малиновым. Парные строки и 0 сделать одним оттенком серого, непарные - другим. Все.

Честно говоря, я уже совсем исчерпался - незнаю в какую сторону копать. Ведь вопрос не в том, что неработает Custom Draw, а в том, что НЕ ОСУЩЕСТВЛЯЕТСЯ ПЕРЕХОД НА ТОТ CASE, КОТОРЫЙ ОТВЕЧАЕТ ЗА СМЕНУ ЦВЕТА И ФОНА.

Это сообщение отредактировал(а) S.A.G. - 31.3.2008, 14:52


--------------------
Вот она задачка: спасти себя от себя самого © Cube
Sometimes good people do evil things © A Simple Plan
PM   Вверх
S.A.G.
Дата 31.3.2008, 15:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


не эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1339
Регистрация: 20.7.2006
Где: in ad equate

Репутация: нет
Всего: 19



И еще один любопытный факт: если в switch добавляю default с любым кодом, то на default НИКОГДА не осуществляется переход также, как и на нужный CDDS_ITEMPREPAINT. Т.е. даже после возврата CDRF_NOTIFYITEMDRAW всеравно в dwDrawStage оказывается CDDS_PREPAINT :((

Добавлено через 1 минуту и 46 секунд
Ничего, что я заполняю контрол в обработчике инициализации диалога?


--------------------
Вот она задачка: спасти себя от себя самого © Cube
Sometimes good people do evil things © A Simple Plan
PM   Вверх
korian
Дата 31.3.2008, 17:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 4
Всего: 17



кажися я понял в чем проблема  smile 
обработку WM_NOTIFY надо делать на уровне ListView =)
при использовании MFC, оно само это делает и выводит его на уровень диалога, поэтому я сразу не въехал.
щас попробую и выложу что получилось.

PM   Вверх
korian
Дата 31.3.2008, 17:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 4
Всего: 17



фигню сказал в прошлом посте...
вот так вот:
Код

BOOL CALLBACK DlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
        HANDLE_MSG(hwnd, WM_INITDIALOG, DlgOnInitDialog);
        HANDLE_MSG(hwnd, WM_COMMAND, DlgOnCommand);
    case WM_NOTIFY:
        {
            long lResult = DlgOnNotify(hwnd, wParam, (NMHDR*)lParam);

         // This is the way a dialog box can send back lresults.. 
         // See documentation for DialogProc for more information
            SetWindowLong(hwnd, DWL_MSGRESULT, lResult); 
            return TRUE;
        }
        default: return FALSE;
    }
}
long DlgOnNotify(HWND hwnd, INT zxc, NMHDR * pnmh)
{
    NMLVCUSTOMDRAW * lpNMCustomDraw = (NMLVCUSTOMDRAW *)pnmh;
    if ((pnmh->hwndFrom == hWndLV1) && (pnmh->code == NM_CUSTOMDRAW))
    {
        switch (lpNMCustomDraw->nmcd.dwDrawStage)
        {
        case CDDS_PREPAINT:
            return CDRF_NOTIFYITEMDRAW;
        case CDDS_ITEMPREPAINT:
            lpNMCustomDraw->clrText = RGB(255, 0, 0); //СЮДА ПРОГРАММА НЕ ДОХОДИТ
            lpNMCustomDraw->clrTextBk = RGB(255, 255, 255);
            return CDRF_NEWFONT;
        }
    }
    return 0;
}


и еще некоторые наблюдения:
hWndLV1 = FindWindowEx(hwnd, NULL, WC_LISTVIEW, "1");
hWndLV1 = GetDlgItem(hwnd, IDC_LIST1);


Это сообщение отредактировал(а) korian - 31.3.2008, 17:54
PM   Вверх
S.A.G.
Дата 31.3.2008, 18:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


не эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1339
Регистрация: 20.7.2006
Где: in ad equate

Репутация: нет
Всего: 19



Ща попробую разобраться..

Это сообщение отредактировал(а) S.A.G. - 31.3.2008, 18:09


--------------------
Вот она задачка: спасти себя от себя самого © Cube
Sometimes good people do evil things © A Simple Plan
PM   Вверх
S.A.G.
Дата 31.3.2008, 18:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


не эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1339
Регистрация: 20.7.2006
Где: in ad equate

Репутация: нет
Всего: 19



Почитал "Remarks" к WM_NOTIFY в MSDN "If the message handler is in a dialog box procedure, you must use the SetWindowLong function with DWL_MSGRESULT to set a return value." -> ну, это мне мало о чем говорит. Эх - снова в макросы лезть, разбираться. Так зачем нужна эта процедура? В каких еще случаях кроме WM_NOTIFY она требуется?


--------------------
Вот она задачка: спасти себя от себя самого © Cube
Sometimes good people do evil things © A Simple Plan
PM   Вверх
S.A.G.
Дата 31.3.2008, 18:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


не эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1339
Регистрация: 20.7.2006
Где: in ad equate

Репутация: нет
Всего: 19



Чем неугодила стандартная распаковка? Подводные камни.. мог бы так неделю сидеть, пока бы не наткнулся на нужное место..((((


--------------------
Вот она задачка: спасти себя от себя самого © Cube
Sometimes good people do evil things © A Simple Plan
PM   Вверх
korian
Дата 31.3.2008, 18:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 4
Всего: 17



когда создается простое окно используется такая симантика функции-обработчика:
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
The return value is the result of the message processing and depends on the message sent.

и функция описывается примерно так:
switch(uMsg)
{
...
default: return DefWindowProc(...);
}


когда создается диалог, такая:
INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
Typically, the dialog box procedure should return TRUE if it processed the message, and FALSE if it did not. If the dialog box procedure returns FALSE, the dialog manager performs the default dialog operation in response to the message.

функция выглядет так:
switch(uMsg)
{
...
default: return 0;
}


т.е. у функции-обработчика диалога нету возможности вернуть LRESULT.
чтобы вернуть LRESULT, надо использовать SetWindowLong(hwnd, DWL_MSGRESULT, lResult);
получается она требуется во всех случаях, если используется диалог и сообщение требует возврата значения LRESULT.
правда есть исключения:
Цитата

The following messages are exceptions to the general rules stated above. Consult the documentation for the specific message for details on the semantics of the return value.

WM_CHARTOITEM
WM_COMPAREITEM
WM_CTLCOLORBTN
WM_CTLCOLORDLG
WM_CTLCOLOREDIT
WM_CTLCOLORLISTBOX
WM_CTLCOLORSCROLLBAR
WM_CTLCOLORSTATIC
WM_INITDIALOG
WM_QUERYDRAGICON
WM_VKEYTOITEM


Добавлено через 14 минут и 8 секунд
получается, в общем случае, макрос HANDLE_MSG не очень подходит для функции-обработчика диалога.

Это сообщение отредактировал(а) korian - 31.3.2008, 18:39
PM   Вверх
S.A.G.
Дата 31.3.2008, 19:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


не эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1339
Регистрация: 20.7.2006
Где: in ad equate

Репутация: нет
Всего: 19



korian, спасибо за ликбез, но ведь функция-обработчик WM_NOTIFY имеет тип BOOL? Т.е., поидее ничего не должно возвращаться длиннее BOOL? И макрос подойдет?


--------------------
Вот она задачка: спасти себя от себя самого © Cube
Sometimes good people do evil things © A Simple Plan
PM   Вверх
korian
Дата 31.3.2008, 19:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 4
Всего: 17



объясняю популярней  smile 
можно сказать что для диалога, WindowProc создается системой и имеет примерно такой вид:

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    if (UserDefinedDlgProc(...))
    {
         return GetWindowLong(hwnd, DWL_MSGRESULT);
    }
    return DefWindowProc(...);
}

поэтому, если используется диалог, все что мы возвращаем из нашей функции-обработчика (UserDefinedDlgProc) не имеет смысла, кроме как true или false.
правда, еще раз скажу, есть исключения описанные выше.

Добавлено @ 19:21
чтобы использовать макросы HANDLE_MSG надо сделать обратное преобразование.
только надо учесть исключения.

Это сообщение отредактировал(а) korian - 31.3.2008, 19:28
PM   Вверх
korian
Дата 31.3.2008, 19:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 4
Всего: 17



Цитата(S.A.G. @  31.3.2008,  18:08 Найти цитируемый пост)
но ведь функция-обработчик WM_NOTIFY имеет тип BOOL

это вы с чего взяли? все сообщения имееют тип возврата LRESULT, кроме опять же исключений, связанных с диалогом.


Это сообщение отредактировал(а) korian - 31.3.2008, 19:39
PM   Вверх
S.A.G.
Дата 1.4.2008, 10:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


не эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1339
Регистрация: 20.7.2006
Где: in ad equate

Репутация: нет
Всего: 19



korian, т.е. получается, что если использовать свое главное окно, а не диалог, то оконная функция расширяет BOOL(int), возвращаемый функцией-обработчиком, до LRESULT (т.е., какбы, расширяет BOOL). Т.е., возвращаемое обработчиком сообщение умещается в BOOL, а системе необходим LRESULT, который диалоговая функция обеспечить неможет и используется иной механизм - SetWindowLong() & return TRUE. Сейчас почитаю про оконную функцию диалога..


--------------------
Вот она задачка: спасти себя от себя самого © Cube
Sometimes good people do evil things © A Simple Plan
PM   Вверх
S.A.G.
Дата 1.4.2008, 10:52 (ссылка) |   (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


не эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1339
Регистрация: 20.7.2006
Где: in ad equate

Репутация: нет
Всего: 19



korian, скиньте, пожалуйста, ссылку на статью в MSDN, где можно прочитать про обработку сообщений диалоговыми окнами.

Добавлено через 2 минуты и 4 секунды
Я все-таки немного непонимаю, InitDialog тоже возвращает BOOL и такое проходит, т.е. в функции диалога return => результат обработки, а в случае WM_NOTIFY такое не прокатывает? Ведь данные-то умещаются в BOOL(int)?


--------------------
Вот она задачка: спасти себя от себя самого © Cube
Sometimes good people do evil things © A Simple Plan
PM   Вверх
korian
Дата 1.4.2008, 11:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 4
Всего: 17



ммм. наверно не так.
это логически разные типы возврата вообще. не понимаю что значит расширяет... в общем случае, когда используется обычное окно, мы полюбому должны обработать сообщение (даже если это вызов DefWindowProc) и возвращаем ответ на сообщение (LRESULT).
С диалогом, есть возможность сообщить - обработали ли мы данное сообщение (TRUE) или система должна сама этим заниматься (FALSE). LRESULT в диалоге можно возвратить только с помощью SetWindowLong.


Это сообщение отредактировал(а) korian - 1.4.2008, 11:04
PM   Вверх
Earnest
Дата 1.4.2008, 12:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 33
Всего: 183



У любого окна есть WindwoProc, которая должна возвращать LRESULT, у диалога тоже. Только в последнем случае она имеет стандартный вид и пользователю дают возможность изменить ее часть, которая называется DialogProc, вот и все. N/t/ DialogProc - это часть WindowProc. 


--------------------
...
PM   Вверх
Страницы: (3) [Все] 1 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0791 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.