Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> окно на API, пытаюсь написать оконный класс 
:(
    Опции темы
_hunter
Дата 29.6.2003, 13:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

Репутация: 16
Всего: 98



Код
class CWindow {
 public:
   CWindow (HINSTANCE);
 private:
   WNDCLASS _class;
   HWND _hwnd;
   static LRESULT CALLBACK WindowProcedure(HWND, UINT, WPARAM, LPARAM);
};

LRESULT CALLBACK CWindow::WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
 switch (message) {
   case WM_DESTROY:
     ::PostQuitMessage (0);
     return 0;
 }
 return ::DefWindowProc(hwnd, message, wParam, lParam );
};

CWindow::CWindow(HINSTANCE hInstance) {
 //...
 _class.lpfnWndProc = WindowProcedure;
 //...
};


так все работает, но есть проблема с вызовом классов-членов CWindow.
если так: LRESULT CALLBACK WindowProcedure(HWND, UINT, WPARAM, LPARAM);, то получаю ошибку "Member function must be called or its address taken"

Подскажите как сделать такой класс без static фунции.


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
RAN
Дата 29.6.2003, 16:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Экс. модератор
Сообщений: 709
Регистрация: 14.3.2003
Где: Щёлково Моск.обл.

Репутация: 5
Всего: 6



_hunter, а чего мой вариант не понравился? Вот ссылка
Мне кажется без static не получится, просто у функции без static при компиляции не известен адрес (она ведь может быть перегружена, например). А функции с static нет this (т.е. объекта), поэтому надо указывать объект.
Не знаю чем тебе GetWindowLong не понравилься. Если придумаешь другой способ напиши что-ли, очень интересно.
PM MAIL ICQ   Вверх
RAN
Дата 29.6.2003, 17:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Экс. модератор
Сообщений: 709
Регистрация: 14.3.2003
Где: Щёлково Моск.обл.

Репутация: 5
Всего: 6



Вот тебе пример: (не проверял)
В начале WinMain вызываешь RegisterClasses, а в конце UnregisterClasses.

Код

HINSTANCE hInst; //глобальная переменная, инициализируется в WinMain до вызова всех функций

void RegisterClasses()
//Регистрирует в начале программы все используемые в программе классы окон
{
   WNDCLASS wcl;

   wcl.style = CS_DBLCLKS;
   wcl.lpfnWndProc = CWindow::WindowProcedure;
   wcl.cbClsExtra = 0;
   wcl.cbWndExtra = 4; //4 байта для this объекта (хотя можно использовать и GWL_USERDATA)
   wcl.hInstance = hInst;
   wcl.hIcon = NULL;
   wcl.hCursor = LoadCursor(NULL, IDC_ARROW);
   wcl.hbrBackground = NULL;
   wcl.lpszMenuName = NULL;
   wcl.lpszClassName = "CWindow";
   RegisterClass(&wcl);

}

//---------------------------------------------------------------------------
void UnregisterClasses()
//Удаляет все классы окон из памяти при завершении программы
{
   UnregisterClass("CWindow", hInst);
}

class CWindow {
public:
  CWindow (const char* Title, int Style, int left, int top, int width, int height, HWND hParent);
private:
  HWND _hwnd;
  static LRESULT CALLBACK WindowProcedure(HWND, UINT, WPARAM, LPARAM);
  OnPaint(HDC DC, RECT rect);
};

CWindow::CWindow(const char* Title, /*Заголовок окна*/
                int Style, /* Стиль окна */
                int left, int top, int width, int height /*позиция и размер*/,
                HWND hParent /* родительское окно, NULL - если нет */
) {
//...

 _hwnd = CreateWindow("CWindow", Title, Style,
            left, top,  width, height, hParent, NULL, hInst, NULL);
 SetWindowLong(_hwnd, 0, (LONG) this);

//...
}

LRESULT CALLBACK CWindow::WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
CWindow* cls = (CWindow*)GetWindowLong(hwnd, 0);
switch (message) {
    case WM_PAINT:
        {
        PAINTSTRUCT ps;
        HDC DC = BeginPaint(hwnd, &ps);
        cl->OnPaint(DC, ps.rcPaint);
        EndPaint(hwnd, &ps);
        }
        return 0;
  case WM_DESTROY:
    PostQuitMessage (0);
    return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam );
}


Есть один серьёзный недостаток, неизвестно когда сработает SetWindowLong, поэтому может получиться в cls нечто и будет ошибка. У меня правда всё работает.

Это сообщение отредактировал(а) RAN - 29.6.2003, 17:23
PM MAIL ICQ   Вверх
_hunter
Дата 29.6.2003, 20:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

Репутация: 16
Всего: 98



Все хорошо, но на wcl.lpfnWndProc = CWindow::WindowProcedure; получаю сообщение о недоступности.


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
RAN
Дата 30.6.2003, 09:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Экс. модератор
Сообщений: 709
Регистрация: 14.3.2003
Где: Щёлково Моск.обл.

Репутация: 5
Всего: 6



Ой, ты прав надо в классе CWindow объявить friend void RegisterClasses();
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

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


 




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


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

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