Api

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

lazybiz

Well-known member
03.11.2010
1 339
0
#2
Всем доброго времени суток!
Доброго!
Я постараюсь тебе все объяснить.
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;
}
 
15.12.2010
15
0
#3
Доброго!
Я постараюсь тебе все объяснить.
hInstance - никакого отношения к окнам не имеет. Это хэндл файла (процесса)...
Вот это спасибо! :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: хотелось бы такой же содержательный ответ, спасибо!
 

lazybiz

Well-known member
03.11.2010
1 339
0
#4
не хотелось, конечно, глобалную переменную объявлять
Это почему же?

Попробуй вот так:
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' ! У тебя был один.
Да и вообще у тебя слишком много всего что можно исправить. Более содержательный ответ писать некогда, извини.
 
15.12.2010
15
0
#5
15.12.2010
15
0
#7
Еще раз привет, работникам int'а и цикла!
Хочу создать модальный диалог, где будут выбраны какие либо файлы с помощью OPENFILENAME.
Для этого нужно создать класс... вот тут то я и не могу сообразить как его описывать(( с гл.фреймом все понятно, более или менее, а вот тут... помогите плиз!
 

lazybiz

Well-known member
03.11.2010
1 339
0
#8
AntoniM
Ты не знаешь что такое класс и как его описать в общем смысле, или же ты не может совместить с классом свои функции?
 
15.12.2010
15
0
#9
AntoniM
Ты не знаешь что такое класс и как его описать в общем смысле, или же ты не может совместить с классом свои функции?
За сегодня разобрался со всем)) неть ! знаю!))) ;)

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

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

lazybiz

Well-known member
03.11.2010
1 339
0
#10
Нужно просто регить класс главного фрэйма прямо в WinMain
Да, и создавать окно в WinMain, и все остальные функции которым необходим hInstance тоже вызывать из WinMain. Все верно!
Только вот блин как же быть если функцию, требующую hInstance, необходимо вызвать из WndProc... загадка!
 
15.12.2010
15
0
#12
Еще раз привет!
Столкнулся с такой задачей, и никак не пойму с какой стороны к ней подкрасться:
Есть необходимость создавать объект некого класса, имя которого до непосредственного объявления не известно, как быть?(желательно пример или где искать, ибо не смог в инете найти)
...и еще как мне заставить EditBox принимать только число или только текст?
Заранее благодарен!
 
15.12.2010
15
0
#13
P.S.: да и спросил забыть - кто главный/распространенный/самый-самый/или еще какой - Юникод или Анси? А то тут покопавшись на форумах увидел что иногда кодировки "выкидывают" не приятные сюрпрайзы.
 

lazybiz

Well-known member
03.11.2010
1 339
0
#15
На сколько я знаю, элемент EditBox может содержать символы и цифры в зависимости от стиля его создания. Создай новую тему.