Api

Тема в разделе "MS Visual C++", создана пользователем Antonim, 14 июл 2011.

  1. Antonim

    Antonim Member

    Регистрация:
    15 дек 2010
    Сообщения:
    15
    Симпатии:
    0
    Всем доброго времени суток!
    Объясните, пожалуйста, как мне в любом месте программы получить hInstance главного окна моей программы?(vcpp6+API)
    ... нашел на MSDN и RSDN - GetModuleHandle(NULL); - но это для консольных приложений вроде бы.
    Заранее спасибо за помощь.
     
  2. lazybiz

    lazybiz Well-Known Member
    C\C++ Team

    Регистрация:
    3 ноя 2010
    Сообщения:
    1.344
    Симпатии:
    0
    Доброго!
    Я постараюсь тебе все объяснить.
    hInstance - никакого отношения к окнам не имеет. Это хэндл файла (процесса).
    Получить hInstance ты можешь с помощью функции GetModuleHandle( NULL ) вне зависимости от того какое у тебя приложение, консольное или оконное. Но!, поскольку ты пишешь оконное приложение VC6, то скорее всего твоя программа имеет точку входа (функцию) WinMain, которая имеет прототип:
    int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
    В этом случае будет правильней объявить глобальную переменную, к примеру назовем ее g_hInstance, которой в самом начале функции WinMain ты можешь присвоить значение параметра hInstance, таким образом тебе не нужно будет каждый раз вызывать функцию GetModuleHandle( NULL ) для получения хэндла процесса, а всего лишь прочитать значение глобальной переменной g_hInstance.
    Пример:
    Код (C++):
    #include <...>

    ... инклуды, переменные, прототипы ...

    HINSTANCE   g_hInstance;

    ...

    void create_window()
    {
    ...
    hWnd = CreateWindow( ... , ... , ... , ... , ... , ... , ... , ... , ... , g_hInstance, ... );
    ...
    }

    int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
    {
    g_hInstance = hInstance;

    ... регистрация класса ...

    create_window();

    ...

    return 0;
    }
     
  3. Antonim

    Antonim Member

    Регистрация:
    15 дек 2010
    Сообщения:
    15
    Симпатии:
    0
    Вот это спасибо! :lool:

    Да, действительно, WinMain() присутствует) не хотелось, конечно, глобалную переменную объявлять, ну ежели никак иначе, то ладно)

    у меня возникла другая трабла:
    Класс окна зарегистрировал, инициализаровал, вообщем все нормально кроме одного -
    в созданном мной меню, по нажатии "открыть" ничего не происходит(( хотя код обработки выбора этого меню работает 100%(вообще компилируется все без ошибок и запуск никаких ошибок не вызывает)
    Конкретней GetOpenFileName и GetSaveFileName возвращают 0. почему? не пойму...

    Листинг проблемы:

    Код (C++):
    LRESULT CALLBACK WndProc(HWND hMainWnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    ...
    static OPENFILENAME ofn;
    static char szFile[256];
    static char szFileTitle[256];
    static char CustomFilter[256];

    switch (msg)
    {
    case WM_CREATE:
    {
    ofn.lStructSize     = sizeof(OPENFILENAME);
    ofn.hwndOwner       = hMainWnd;
    ofn.nFilterIndex        = 1;
    ofn.lpstrFile       = szFile;
    ofn.nMaxFile        = sizeof(szFile);
    ofn.lpstrFileTitle      = szFileTitle;
    ofn.nMaxFileTitle       = sizeof(szFileTitle);
    ofn.lpstrCustomFilter   = CustomFilter;
    return 0;
    }
    case WM_COMMAND:
    {
    switch(LOWORD(wParam))
    {
    case CM_FILE_OPEN:
    {
    ofn.Flags = OFN_EXPLORER | OFN_CREATEPROMPT | FN_ALLOWMULTISELECT;
    ofn.lpstrTitle = "Открыть Файл";
    char szFilter[256]="All Files\0*.*\0";
    ofn.lpstrFilter=szFilter;
    szFileTitle[0]='\0';
    szFile[0]='\0';
    if (GetOpenFileName(&ofn))
    {
    char str[512];
    strcpy(str,"Список имен файлов:\t");
    for (usint i = 0; i<255;i++)
    {
    if(szFile[i]=='\0' && szFile[i+1]=='\0') break;
    if(szFile[i]=='\0') szFile[i]='\n';
    }
    strcat(str,szFile);
    strcat(str,"\n\nИмя файла без указания пути:\t");
    strcat(str,szFileTitle);
    MessageBox(hMainWnd,str,"Результат выбора имени открываемого файла",MB_OK);
    }
    else
    MessageBox(hMainWnd,"Не возможен вызов GetOpenFileName();","Неполадка",MB_OK);
    return 0;
    }
    ...
    получаю - "Не возможен вызов GetOpenFileName();"

    Добавлено: :blush: хотелось бы такой же содержательный ответ, спасибо!
     
  4. lazybiz

    lazybiz Well-Known Member
    C\C++ Team

    Регистрация:
    3 ноя 2010
    Сообщения:
    1.344
    Симпатии:
    0
    Это почему же?

    Попробуй вот так:
    Код (C++):
            case CM_FILE_OPEN:
    {
    char            filename[256] = "\0";
    OPENFILENAME    ofn;

    ZeroMemory( &ofn, sizeof( OPENFILENAME ) );
    ofn.lStructSize         = sizeof( OPENFILENAME );
    ofn.lpstrFilter         = "All Files\0*.*\0\0";
    ofn.lpstrFile           = filename;
    ofn.nMaxFile            = 256;
    ofn.Flags               = OFN_ALLOWMULTISELECT | OFN_CREATEPROMPT | OFN_EXPLORER;

    if ( GetOpenFileName( &ofn ) ) {
    MessageBox( hWnd, filename, "ок", MB_OK );
    } else {
    MessageBox( hWnd, "файл не выбран", "ошибка", MB_OK );
    }
    } break;
    Все другие переменные, относящиеся к функции GetOpenFileName удали.

    Скорее всего ошибкой была инициализация ofn.lpstrFilter. Значением ее параметра должен быть указатель на строку оканчивающуюся двойным символом '\0' ! У тебя был один.
    Да и вообще у тебя слишком много всего что можно исправить. Более содержательный ответ писать некогда, извини.
     
  5. Antonim

    Antonim Member

    Регистрация:
    15 дек 2010
    Сообщения:
    15
    Симпатии:
    0
    ну вроде Страутруп с Либерти(остальных уже выборочно читал) говорят что от глобальных переменных надо уходить)
    Попробую, Спасибо!
     
  6. Antonim

    Antonim Member

    Регистрация:
    15 дек 2010
    Сообщения:
    15
    Симпатии:
    0
    :blush: работаит)))
     
  7. Antonim

    Antonim Member

    Регистрация:
    15 дек 2010
    Сообщения:
    15
    Симпатии:
    0
    Еще раз привет, работникам int'а и цикла!
    Хочу создать модальный диалог, где будут выбраны какие либо файлы с помощью OPENFILENAME.
    Для этого нужно создать класс... вот тут то я и не могу сообразить как его описывать(( с гл.фреймом все понятно, более или менее, а вот тут... помогите плиз!
     
  8. lazybiz

    lazybiz Well-Known Member
    C\C++ Team

    Регистрация:
    3 ноя 2010
    Сообщения:
    1.344
    Симпатии:
    0
    AntoniM
    Ты не знаешь что такое класс и как его описать в общем смысле, или же ты не может совместить с классом свои функции?
     
  9. Antonim

    Antonim Member

    Регистрация:
    15 дек 2010
    Сообщения:
    15
    Симпатии:
    0
    За сегодня разобрался со всем)) неть ! знаю!))) ;)

    Добавлено: и действительно кое что модифицировал в коде - лишнее в сторону, как грица))

    Добавлено: И как писал выше я все таки нашел способ ухода от объявления hInstance как глобальной переменной!
    Нужно просто регить класс главного фрэйма прямо в WinMain(...){...} и тогда объявив в WndProc(...){...} её как static все встает на свои места!
     
  10. lazybiz

    lazybiz Well-Known Member
    C\C++ Team

    Регистрация:
    3 ноя 2010
    Сообщения:
    1.344
    Симпатии:
    0
    Да, и создавать окно в WinMain, и все остальные функции которым необходим hInstance тоже вызывать из WinMain. Все верно!
    Только вот блин как же быть если функцию, требующую hInstance, необходимо вызвать из WndProc... загадка!
     
  11. Antonim

    Antonim Member

    Регистрация:
    15 дек 2010
    Сообщения:
    15
    Симпатии:
    0
    Легко ведь мы объявили в ней hInstance как static.
    Или я предложение не понял ;)
     
  12. Antonim

    Antonim Member

    Регистрация:
    15 дек 2010
    Сообщения:
    15
    Симпатии:
    0
    Еще раз привет!
    Столкнулся с такой задачей, и никак не пойму с какой стороны к ней подкрасться:
    Есть необходимость создавать объект некого класса, имя которого до непосредственного объявления не известно, как быть?(желательно пример или где искать, ибо не смог в инете найти)
    ...и еще как мне заставить EditBox принимать только число или только текст?
    Заранее благодарен!
     
  13. Antonim

    Antonim Member

    Регистрация:
    15 дек 2010
    Сообщения:
    15
    Симпатии:
    0
    P.S.: да и спросил забыть - кто главный/распространенный/самый-самый/или еще какой - Юникод или Анси? А то тут покопавшись на форумах увидел что иногда кодировки "выкидывают" не приятные сюрпрайзы.
     
  14. Antonim

    Antonim Member

    Регистрация:
    15 дек 2010
    Сообщения:
    15
    Симпатии:
    0
    чёто туд усе погибли похоже ;)
     
  15. lazybiz

    lazybiz Well-Known Member
    C\C++ Team

    Регистрация:
    3 ноя 2010
    Сообщения:
    1.344
    Симпатии:
    0
    На сколько я знаю, элемент EditBox может содержать символы и цифры в зависимости от стиля его создания. Создай новую тему.
     
  16. Antonim

    Antonim Member

    Регистрация:
    15 дек 2010
    Сообщения:
    15
    Симпатии:
    0
    оке, тему в офф)... ;)
     
Загрузка...

Поделиться этой страницей