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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Функция CreateWindow, Возвращает NULL почему-то... 
:(
    Опции темы
BadPointer
Дата 7.9.2009, 17:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 7.9.2009

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



Здравствуйте! Помогите разобраться с ошибкой- вызываю функциию CreateWindow, все параметры на мой взгляд верны, а она возвращает NULL.  Функции главного окна организованны в класс:

PlayerClass.h

Код


#pragma once

class DPlayer
{
public:

    DPlayer();
    ~DPlayer();

    HRESULT PlayMovie(string lpFileName); //Играть видео
    HRESULT InitializeInterfaces(); //инициализация Com  объектов
    HRESULT ReleaseInterfaces(); //Освобождение Com объектов
    HRESULT InitInstance(HINSTANCE hInstance,int nCmdShow); //Создаем окно, показываем


    static LRESULT CALLBACK WindowProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);

    LPCSTR ClassName()  { return TEXT("DPlayer"); }; //Имя класса окна
    LPCSTR WindowName() { return TEXT("DPlayerWindow"); }; //Имя окна
    LPCSTR MenuName()   { return NULL;}; //Меню

private:
    IGraphBuilder *pGB;
    IMediaControl *pMC;
    IMediaEvent   *pME;
    IVideoWindow  *pVW;

    HWND      m_hMainWnd; //Главное окно
    HINSTANCE m_hInstance; 

};



PlayerClass.cpp

Код

#include"stdafx.h"

//Конструктор
DPlayer::DPlayer()
{
    this->pGB=NULL;
    this->pMC=NULL;
    this->pME=NULL;
    this->pVW=NULL;
    this->m_hMainWnd=NULL;
    this->m_hInstance=NULL;

}
//Инициализация интерфейсов для воспроизведения видео
HRESULT DPlayer::InitializeInterfaces()
{
    HRESULT hr=S_OK;
    hr=CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC,IID_IGraphBuilder,(void**)&pGB);
    if(hr==S_OK)
    {
        hr=pGB->QueryInterface(IID_IVideoWindow,(void**)&pVW);
        if(hr==S_OK)
        {
            hr=pGB->QueryInterface(IID_IMediaControl,(void**)&pMC);
            if(hr==S_OK)
            {
                hr=pGB->QueryInterface(IID_IMediaEvent,(void**)&pME);
                MessageBox(0,"Инициализация прошла успешно","Notify",0);
                return S_OK;
            }
            else{return S_FALSE;}
        }
        else{return S_FALSE;}
    }
    else{return S_FALSE;}
}

//Освобождаем интерфейсы
HRESULT DPlayer::ReleaseInterfaces()
{
    this->pGB->Release();
    this->pVW->Release();
    this->pMC->Release();
    this->pME->Release();

    return S_OK;
}

//Инициализируем окно и показываем его
HRESULT DPlayer::InitInstance(HINSTANCE hInstance,int nCmdShow)
{
    WNDCLASSEX wcex;
    ZeroMemory(&wcex,sizeof(wcex));

    wcex.cbSize=sizeof(WNDCLASSEX);

    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = 0;
    wcex.hbrBackground  = (HBRUSH)COLOR_WINDOW+1;
    wcex.hCursor        = LoadCursor(NULL,IDC_ARROW);
    wcex.hIcon          = (HICON)NULL;
    wcex.hIconSm        = (HICON)NULL;
    wcex.hInstance      = hInstance;
    wcex.lpfnWndProc    = WindowProc;
    wcex.lpszClassName  = ClassName();
    wcex.lpszMenuName   = MenuName();
    wcex.style          = CS_HREDRAW | CS_VREDRAW;

    if(RegisterClassEx(&wcex)==0)
    {
        MessageBox(0,"Ошибка вызова функции регистрации класса окна","Error",MB_ICONERROR);
        return S_FALSE;
    }

    this->m_hInstance=hInstance;

    //Ошибка, окно не создается
    HWND hWnd=CreateWindowA(ClassName(),WindowName(),WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,0,CW_USEDEFAULT,0,NULL,NULL,hInstance,NULL);

    
    if(hWnd!=0)
    {
        this->m_hMainWnd=hWnd;
        ShowWindow(hWnd,nCmdShow);
        UpdateWindow(hWnd);
        return S_OK;
    }
    else
    {
        MessageBox(NULL,"Ошибка вызова функции создания окна","Error",MB_ICONERROR);
        return S_FALSE;
    }
}
        
LRESULT CALLBACK DPlayer::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
    case WM_QUIT:
        PostQuitMessage(0);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    case WM_CLOSE:
        PostQuitMessage(0);
        break;
    default:
        DefWindowProc(hWnd,message,wParam,lParam);
    }
    return 0;
}




WinMain.cpp

Код


#include"stdafx.h"

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
    MSG msg;
    DPlayer *player=new DPlayer();

    CoInitialize(NULL);

    player->InitializeInterfaces();
    player->InitInstance(hInstance,nCmdShow);

    while(GetMessage(&msg,0,0,0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    CoUninitialize();

    return 0;
}



Stdafx.h

Код


#pragma once

#include"string"
#include"vector"
using namespace std;
#include"dshow.h"
#include"strsafe.h"
#include"playerclass.h"
#include"resource.h"

#pragma comment(lib,""Strmiids.lib")



Это все файлы проекта.
PM MAIL   Вверх
GremlinProg
Дата 7.9.2009, 23:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



процедура окна должна все таки возвращать осмысленное значение, а не ноль,
особенно в тех случаеях, когда ей нечего ответить:
Код

LRESULT CALLBACK DPlayer::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    }
    return DefWindowProc(hWnd,message,wParam,lParam);
}



--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Earnest
Дата 8.9.2009, 11:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Скорее всего, ты отшиб стандартный обработчик WM_CREATE. Сделай так, как показал
GremlinProg, т.е. вызывай DefWindowProc для необрабатываемых сообщений.


--------------------
...
PM   Вверх
TGrey
Дата 8.9.2009, 11:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 1.12.2007

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



Да уж, проверенно обработчик окна всегда должен возвращать DefWindowProc. В твоем случае ошибка заключается в том, что у тебя в default: стоит обычный вызов этой функции, а не ее возврат.
Поэтому достаточно писать
default:
       return DefWindowProc(...);

а последний return отпадает т.к. default словит все, что не обрабатывается и до конца функции не дойдет.

Это сообщение отредактировал(а) TGrey - 8.9.2009, 12:03
PM MAIL   Вверх
GremlinProg
Дата 8.9.2009, 12:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(TGrey @  8.9.2009,  13:49 Найти цитируемый пост)
А причем тут обработчик?

обработчик очень даже причем:
Цитата(WM_NCCREATE @ MSDN)

If an application processes this message, it should return TRUE to continue creation of the window. If the application returns FALSE, the CreateWindow or CreateWindowEx function will return a NULL handle. 

Цитата(TGrey @  8.9.2009,  13:49 Найти цитируемый пост)
Окно должно создаваться и без него, просто не будет обрабатывать ничего

ни в коем разе, процедура окна - обязательная его составляющая
Цитата(TGrey @  8.9.2009,  13:49 Найти цитируемый пост)
Темболее default и так словит все не обрабатываемые сообщения, так что разницы нет

default тут ни при чем,
смысл не в том, что он отловит все не обрабатываемые сообщения,
а в том, что результат работы процедуры окна не должен быть нулевым

Добавлено через 7 минут и 48 секунд
Цитата(TGrey @  8.9.2009,  13:49 Найти цитируемый пост)
а последний return отпадает т.к. default словит все, что не обрабатывается и до конца функции не дойдет.

нет, не отпадает,
все сообщения, которые не попадут в default должны также вернуть результат,
TGrey, почитай чтоли литературу по си, прежде чем разбрасываться неуместными советами,
а про switch с default у нас был отдельный разговор:
почему его нежелательно использовать в процедуре окна,
и к чему это может привести,
полистай поиск


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
TGrey
Дата 8.9.2009, 12:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 1.12.2007

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



Для начала я только в конце заметил, что у него вызов функции DefWindowProc, а не возврат. Поэтому и написал, то что написал. Насчет без него я имел ввиду DefWindowProc, а не всего обработчика, тут я не спорю, думал, что можно и возвращать что-то иное.
И каким это боком последний ретурн может не отпасть если в switch стоит default??  Он вроде для того и сделан, чтобы ловить все, что не ловят caseы и тогда и так ясно, что если в него всунуть return DefWindowProc(...); то до последнего ретурна не дойдет очередь.
Я то понял, что даже после обработанного сообщения нужно вернуть DefWindowProc, но я говорил конкретно про не обрабатываемые сообщения.


И заметив ошибку я отредактировал вроде раньше, чем ты добавил замечания в мою сторону.

Это сообщение отредактировал(а) TGrey - 8.9.2009, 12:47
PM MAIL   Вверх
GremlinProg
Дата 8.9.2009, 12:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(TGrey @  8.9.2009,  14:39 Найти цитируемый пост)
Для начала я только в конце заметил, что у него вызов функции DefWindowProc, а не возврат

Цитата(TGrey @  8.9.2009,  14:39 Найти цитируемый пост)
И каким это боком последний ретурн может не отпасть если в switch стоит default??

это не имеет значения, даже если бы стоял return DefWindowProc, пришлось бы его дублировать после switch, т.к. case'ы не возвращают результат, даже компилятор тебе должен об этом напомнить
Цитата(TGrey @  8.9.2009,  14:39 Найти цитируемый пост)
И заметив ошибку я отредактировал вроде раньше, чем ты добавил замечания в мою сторону.

слово не воробей, к тому же, ты отредактировал пост опять же неверно,
у меня складывается ощущение, что поиском пользуюсь только я: http://forum.vingrad.ru/forum/topic-260881...y1879209/0.html
ведь тема не такая уж и старая, что стоит ввести в запрос "default"?


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
TGrey
Дата 8.9.2009, 13:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 1.12.2007

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



Так я не спорю, не увидел ошибку - написал не то что нужно.
Да про то что дублировать я ничего против и не имею. Как я уже сказал, что я все же думал, уже так не думаю  smile , что функция может возвращать, что-то другое.
И как уже говорил, в дефолте возврат сработает только если сообщение не обрабатывается.
У меня в статьях по которым я учил это видимо тоже забыли этому уделить внимание и поэтому структура было такова
Код

LRESULT CALLBACK WndProc(HWND hw, UINT msg, WPARAM wparam, LPARAM lparam)
{
    switch(msg)
    {
        case WM_DESTROY: OnDestroy(hw); break;
        case WM_PAINT: OnPaint(hw);
            break;
        default: return DefWindowProc(hw,msg, wparam, lparam);
    }
//end
}

И все работает.
PM MAIL   Вверх
GremlinProg
Дата 8.9.2009, 14:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(TGrey @  8.9.2009,  15:47 Найти цитируемый пост)

LRESULT CALLBACK WndProc(HWND hw, UINT msg, WPARAM wparam, LPARAM lparam)
{
    switch(msg)
    {
        case WM_DESTROY: OnDestroy(hw); break;
        case WM_PAINT: OnPaint(hw);
            break;
        default: return DefWindowProc(hw,msg, wparam, lparam);
    }
//end
}

ни чего не путаешь?
быть может так:
Код

    switch(msg)
    {
        HANDLE_MSG( hw, msg, OnDestroy );
        HANDLE_MSG( hw, msg, OnPaint );
        default: return DefWindowProc(hw,msg, wparam, lparam);
    }

или так:
Код

    switch(msg)
    {
        case WM_DESTROY: return OnDestroy(hw);
        case WM_PAINT: return OnPaint(hw);
        default: return DefWindowProc(hw,msg, wparam, lparam);
    }

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


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
TGrey
Дата 8.9.2009, 14:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 1.12.2007

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



Да в книге Финогенова вроде первый пример без макроса HANDLE_MSG и без ретурна после свича. Дальше вроде макрос используется. А так примеры из интернеты авторов нет как таковых. Функции просто вызываются, а не returnятся.

Блин ты мне открыл глаза! smile 
Просто я писал свои исходники без макроса и весь код писал либо в оконной процедуре либо вызывал функцию. Ужос.
PM MAIL   Вверх
GremlinProg
Дата 8.9.2009, 15:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



первый пример процедуры окна из книги Финогенова "Win32. Основы программирования":
Код

/*Оконная функция WndProc главного окна*/
LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam){
  switch(msg){//Переход по значению msg - номеру сообщения
  case WM_DESTROY://При завершении приложения пользователем
    PostQuitMessage(0);//вызвать функцию Windows завершения приложения
    return 0;//Возврат в Windows
  default://B случае всех остальных сообщений Windows обработка
    return(DefWindowProc(hwnd,msg,wParam,lParam)) ; //их по умолчанию
  }//Конец опера тора switch
}//Конец функции WndProc

тут return и не требуется, т.к. он стоит на всех путях свитча,
вобщем, WinAPI это уже не касается, не надо раздувать оффтопик

Это сообщение отредактировал(а) GremlinProg - 8.9.2009, 15:43


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
BadPointer
Дата 8.9.2009, 16:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 7.9.2009

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



Добавил return DefWindowProc  в WndProc и WM_CREATE:  все заработало!  Кстати не первый раз на такие грабли наступал, а никогда не смотрел что возвращается по дефолту в WndProc. Всем спасибо!
PM MAIL   Вверх
Titeha
Дата 12.5.2010, 10:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 7.2.2010

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



Здравствуйте, уважаемые!

У меня похожая проблема, только я не облекал в класс. Сделал как тут пишите, но CreateWindowEx все-равно возвращает 0, при этом проверка GetLastError возвращает 1407. Не подскажите что может быть?

Код

#include "MyProject.h"

HINSTANCE hInst;
HWND MyProjectWnd;

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
                       LPTSTR lpCmdLine, int nCmdShow)
{
 ATOM MyProjectWndClass;
 WNDCLASSEX wc;
 MSG msg;

 hInst = hInstance;

 wc.cbSize = sizeof(WNDCLASSEX);
 wc.style = CS_HREDRAW | CS_VREDRAW;
 wc.lpfnWndProc = WndProc;
 wc.cbClsExtra = 0;
 wc.cbWndExtra = 0;
 wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MY_ICON));
 wc.hCursor = LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW));
 wc.hbrBackground = (HBRUSH)1;
 wc.lpszMenuName = NULL;
 wc.lpszClassName = static_cast<LPCWSTR> (_TEXT("MyProjectWndClass"));
 wc.hIconSm = wc.hIcon;

 if (!(MyProjectWndClass = RegisterClassEx(&wc)))
  MessageBox(NULL, static_cast<LPCWSTR> (_TEXT("Ошибка запуска программы!")), 
             static_cast<LPCWSTR> (_TEXT("Ошибка")), MB_OK | MB_ICONERROR);

 MyProjectWnd = CreateWindowEx(0, (LPCWSTR)MAKELONG(MyProjectWndClass, 0),
                              static_cast<LPCWSTR> (_TEXT("Этот проект")),
                              WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 
                              CW_USEDEFAULT, CW_USEDEFAULT,    CW_USEDEFAULT, 
                              NULL, NULL, hInstance, NULL);
 if (!MyProjectWnd)// return EXIT_FAILURE;
  {
  DWORD T = GetLastError();
  return EXIT_FAILURE;
  }

 ShowWindow(MyProjectWnd, SW_SHOWNORMAL);

 while (GetMessage(&msg, NULL, 0, 0))
 {
  TranslateMessage(&msg);
  DispatchMessage(&msg);
 }

 return 0;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
 switch    (message)
 {
  case WM_CLOSE:
  {
   DestroyWindow(hWnd);
   break;
  }
  case WM_DESTROY:
  {
   PostQuitMessage(EXIT_SUCCESS);
   break;
  }
  /*default:
   return DefWindowProc(hWnd, message, wParam, lParam);
   break;*/
 }

 return DefWindowProc(hWnd, message, wParam, lParam);
}


В заголовочном файле я подключаю ресурсы и другие заголовочные файлы для нормальной компиляции "проекта".

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

Пишу сюда, так как ответа не нашел, а новую тему создавать считаю лишнем, раз есть похожая.

Спасибо.
PM MAIL   Вверх
GoldFinch
Дата 12.5.2010, 10:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 2
Всего: 26



Цитата(Titeha @  12.5.2010,  11:15 Найти цитируемый пост)
GetLastError возвращает 1407.

напишите текст ошибки, его можно поискать в справке, или вызвать функцию FormatMessage после GetLastError 
PM MAIL ICQ   Вверх
Alca
Дата 12.5.2010, 10:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

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



1407 - Не удается найти класс окна. 


--------------------
PM WWW ICQ Skype Jabber   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "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.0612 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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