Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > ListView в роли таблицы(создание класса)


Автор: devmstr 28.11.2006, 20:39
Я решил создать класс, который позволил бы мне без излишний проблем использовать ListView в качестве компонента для работы с таблицами. Класс я уже почти написал. Но тут появилась одна проблема.
Для реализации возможности редактирования я использую Edit, который при щелчке мышкой по item'у ListView появляется на соответствующем месте. Для этого я заменил очередь обработки сообщений ListView на свою, использую SetWindowLong.
Все бы ничего, но свою функцию мне пришлось в классе объявить как static(чтобы узбавится от 5-го параметра функции - this). Это и спровоцировало осовную проблему. Раз метод статик, то подавай и все используемые переменные и методы в функции как static. Особенно меня раздражает необходимость в их инициализации вне класса(как по другому я не знаю). Да и вообще "красить" весь класс в static из-за одной функции мне бы не хотелось.
Помогите мне, пожайлуста, советом, как мне решить возникшую проблему...

Автор: dumb 29.11.2006, 02:19
Цитата(devmstr @  28.11.2006,  20:39 Найти цитируемый пост)
функцию мне пришлось в классе объявить как static(чтобы узбавится от 5-го параметра функции - this)

бррр.. какой параметр? какой this? причем тут static?! user posted image

ps. ты хоть бы описание класса кинул...

Автор: devmstr 29.11.2006, 08:34
Цитата(dumb @  29.11.2006,  02:19 Найти цитируемый пост)
бррр.. какой параметр? какой this?

Каждой функции класса по умолчанию передается this. Если просто написать что-то ввиде:

h-файл(Объявление класса):
Код

class LV_Manager
{
INT_PTR WINAPI LVMngDlgProc(HWND hDlg, UINT msg, WPARAM wPar, LPARAM lPar);     // не статик

void ConnectEdit();
....
}


cpp:
Код

void LV_Manager::ConnectEdit()
{
...
OldLVProc = (WNDPROC)SetWindowLong(hLV, GWL_WNDPROC, (LONG)LVMngDlgProc);
...
}

то VS это не оценит и ругнется в функции SetWindowLong на LVMngDlgProc. Откуда он знает, что ему делать с this. Главное же отличие static методов от других, состоит в том, что this им не передается. Что для OldLVProc  и требовалось.

Автор: GremlinProg 29.11.2006, 09:15
используй шаблоны и оконные свойства:
Код

template<typename Type,INT_PTR(Type::*method)(UINT msg, WPARAM wPar, LPARAM lPar)>
INT_PTR WINAPI LVMngDlgProc(HWND hDlg, UINT msg, WPARAM wPar, LPARAM lPar){
  return(((Type*)GetWindowLong(hDlg,GWL_USERDATA))->*method)(msg,wPar,lPar);
}

сответственно, свойство GWL_USERDATA нужно при инициализации установить в соответствующий указатель объекта класса,
а в SetWindowLong(hLV, GWL_WNDPROC,...) указать конкретную реализацию шаблона LVMngDlgProc.

Автор: dumb 29.11.2006, 09:21
Цитата(devmstr @  29.11.2006,  08:34 Найти цитируемый пост)
Главное же отличие static методов от других, состоит в том, что this им не передается.

ну... это скорее одно из следствий, нежели "главное отличие"... smile

а что мешает передать this через одно статическое свойство? все равно, я так понял, у тебя экземпляр единственный(если ты уже на пол-пути покрыть все статиком smile ).

Код

class LV_Manager
{
  static LV_Manager *this_ptr;
  static INT_PTR WINAPI LVMngDlgProc(HWND hDlg, UINT msg, WPARAM wPar, LPARAM lPar);
  void ConnectEdit();
  ...
};

LV_Manager *LV_Manager::this_ptr = 0;

void LV_Manager::ConnectEdit()
{
...
  this_ptr = this;
  OldLVProc = (WNDPROC)SetWindowLong(hLV, GWL_WNDPROC, (LONG)LVMngDlgProc);
...
}

INT_PTR WINAPI LV_Manager::LVMngDlgProc(HWND hDlg, UINT msg, WPARAM wPar, LPARAM lPar)
{
  this_ptr->blabla...
  ...
}


ps. думаю, есть еще кучка вариантов много покрасивше, но в голову чтой-то не "йдут"... smile

Автор: devmstr 29.11.2006, 09:37
Основное место, где меня сипает  smile .
Цитата(dumb @  29.11.2006,  09:21 Найти цитируемый пост)
LV_Manager *LV_Manager::this_ptr = 0;

Не хочется мне ничего инициализировать вне класса. Тем более желание попользоватся моим классом есть не только у меня, а "подчеркивать" о том, что обязательно не забудьте инициализировать переменную мне не хочется.

GremlinProg
Ээ. Ну с шаблонами у меня пока туго, каюсь. А мона как-то без них?

Автор: devmstr 29.11.2006, 23:58
Все, проблема решилась. SetWindowLong rules. 
GremlinProg, особое спасибо за идею... 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)