Змінюй хід війни! Допомагай ЗСУ!

Создание диалога файла в си с использованием win32 api

  • Автор теми Автор теми positiveman
  • Дата створення Дата створення

positiveman

Привіт!
Статус: Офлайн
Реєстрація: 27.05.2010
Повідом.: 6
Создание диалога файла в си с использованием win32 api

Нужен диалог для открытия файла в си с использованием win32 api.
Использую среду code::blocks, где нет vcl и MFC. Не надо отправлять меня в гугл, уже кучу инфы пересмотрел, никак не получается сделать.

Чтобы более подробно осветить мою ситуацию, вот код:


Код:
#include <windows.h>

/*  Declare Windows procedure  */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

/*  Make the class name into a global variable  */
char szClassName[ ] = "CodeBlocksWindowsApp";

int WINAPI WinMain (HINSTANCE hThisInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR lpszArgument,
                     int nCmdShow)
{
    HWND hwnd;               /* This is the handle for our window */
    MSG messages;            /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */

    /* The Window structure */
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
    wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
    wincl.cbSize = sizeof (WNDCLASSEX);

    /* Use default icon and mouse-pointer */
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;                 /* No menu */
    wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
    wincl.cbWndExtra = 0;                      /* structure or the window instance */
    /* Use Windows's default colour as the background of the window */
    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;

    /* Register the window class, and if it fails quit the program */
    if (!RegisterClassEx (&wincl))
        return 0;

    /* The class is registered, let's create the program*/
    hwnd = CreateWindowEx (
           0,                   /* Extended possibilites for variation */
           szClassName,         /* Classname */
           "Code::Blocks Template Windows App",       /* Title Text */
           WS_OVERLAPPEDWINDOW, /* default window */
           CW_USEDEFAULT,       /* Windows decides the position */
           CW_USEDEFAULT,       /* where the window ends up on the screen */
           544,                 /* The programs width */
           375,                 /* and height in pixels */
           HWND_DESKTOP,        /* The window is a child-window to desktop */
           NULL,                /* No menu */
           hThisInstance,       /* Program Instance handler */
           NULL                 /* No Window Creation data */
           );

    /* Make the window visible on the screen */
    ShowWindow (hwnd, nCmdShow);

    /* Run the message loop. It will run until GetMessage() returns 0 */
    while (GetMessage (&messages, NULL, 0, 0))
    {
        /* Translate virtual-key messages into character messages */
        TranslateMessage(&messages);
        /* Send message to WindowProcedure */
        DispatchMessage(&messages);
    }

    /* The program return-value is 0 - The value that PostQuitMessage() gave */
    return messages.wParam;
}


/*  This function is called by the Windows function DispatchMessage()  */

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)                  /* handle the messages */
    {
        case WM_DESTROY:
            PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
            break;
            
            
        
        default:                      /* for messages that we don't deal with */
            return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return 0;
}
 
ПУсть бросит в меня камень тот,кто никогда в гавно не вступал.
 
Останнє редагування:
А в чем проблема? Есть же АПИ для того что бы вызвать диалог открытия файла, не помню как называеться точно, но что то типа StartOpenFIleDialog
 
Тыемураз, я не возражаю.
lugal, возможно это как раз то, что мне нужно! До этого я использовал GetOpenFileName, который выдавал ошибку в своем параметре. Может я структуру неправильно определил. Везде пишут, какие поля определять, а что именно в них писать - не ясно.

Вот код, который я использовал раньше:

createWindow.cpp
Код:
//
//createWindow.cpp
//
//
#include <windows.h>
#include "resource.h"
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
#include <Commdlg.h>


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

HINSTANCE hInstance;

int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine,
					  int iCmdShow)
{
	HWND hWnd;
	MSG msg;
	WNDCLASSEX wndclass;

	wndclass.cbSize			=sizeof(WNDCLASSEX);
	wndclass.style			=CS_HREDRAW | CS_VREDRAW;
	wndclass.lpfnWndProc	=WndProc;
	wndclass.cbClsExtra		=0;
	wndclass.cbWndExtra		=0;
	wndclass.hInstance		=hInstance;
	wndclass.hIcon			=LoadIcon(NULL, IDI_APPLICATION);
	wndclass.hCursor		=LoadCursor(NULL, IDC_ARROW);
	wndclass.hbrBackground	=(HBRUSH) GetStockObject(GRAY_BRUSH);
	wndclass.lpszMenuName	="MAIN";
	wndclass.lpszClassName	="Window Class";
	wndclass.hIconSm		=LoadIcon(NULL, IDI_APPLICATION);

	if(!RegisterClassEx(&wndclass))
	{
		exit(1);
	}

	hWnd=CreateWindowEx(
		WS_EX_OVERLAPPEDWINDOW,
		"Window Class",
		"Create Window Example",
		WS_OVERLAPPEDWINDOW,
		0,
		0,
		640,
		480,
		NULL,
		NULL,
		hInstance,
		NULL);

	ShowWindow(hWnd,iCmdShow);

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

	return 0;
}

LRESULT CALLBACK WndProc (HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
	int wmId,wmEvent;
	static int width,height;

	static HWND hButton = NULL;

	static OPENFILENAME ofn;       // common dialog box structure
	static char szFile[260];       // buffer for file name
	static HWND hwnd1;
	static HANDLE hf;				// file handle

	// Initialize OPENFILENAME
	ZeroMemory(&ofn, sizeof(ofn));
	ofn.lStructSize = sizeof(ofn);
	ofn.hwndOwner = hWnd;
	ofn.lpstrFile = szFile;


	switch(iMsg)
	{
	case WM_CREATE:
		hButton = CreateWindowA("button","Browse",
					WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
					10,
					10,
					100,
					20,
					hWnd,
					(HMENU)ID_BUTTON,
					hInstance,
					NULL);

		//
		// Set lpstrFile[0] to '\0' so that GetOpenFileName does not
		// use the contents of szFile to initialize itself.
		//
		ofn.lpstrFile[0] = '\0';
		ofn.nMaxFile = 9999;
		ofn.lpstrFilter = "All\0*.*\0Text\0*.TXT\0";
		ofn.nFilterIndex = 1;
		ofn.lpstrFileTitle = NULL;
		ofn.nMaxFileTitle = 0;
		ofn.lpstrInitialDir = NULL;
		ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;

		break;
	case WM_SIZE:
		width	=LOWORD(lParam);
		height	=HIWORD(lParam);
		break;
	case WM_COMMAND:
		wmId	=LOWORD(wParam);
		wmEvent	=HIWORD(wParam);
		switch (wmId)
		{
		case IDM_EXIT:
			DestroyWindow(hWnd);
			break;
		case IDM_ABOUT:
			if(GetOpenFileName(&ofn)==TRUE)
				MessageBox(NULL,"TRUE",NULL,MB_OK);
            else
				MessageBox(NULL,"FALSE",NULL,MB_OK);

			break;
		case ID_BUTTON:
			GetOpenFileName(&ofn);
			break;
		default:
			return DefWindowProc(hWnd,iMsg,wParam,lParam);
		}
		break;
	case WM_CLOSE:
		DestroyWindow(hWnd);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd,iMsg,wParam,lParam);
	}
	return 0;
}


resource.h
Код:
#define IDM_EXIT	100
#define IDM_ABOUT	101
#define ID_BUTTON	1001


menu.rc
Код:
#include "resource.h"
main MENU
//
//menu.rc
//
{
	POPUP "&File"
	{
		MENUITEM "Exit",IDM_EXIT
	}
	POPUP "Help"
	{
		MENUITEM "About",IDM_ABOUT
	}
}

При этом у меня появлялась ошибка:
obj\Debug\main.o||In function `_Z7WndProcP6HWND__jjl':|
C:\Users\Positivmen\Documents\codeblocks\12\createWindow.cpp|128|undefined reference to `_GetOpenFileNameA@4'|

Подскажите, пожалуйста, как избавиться от этой ошибки, или посоветуйте, как сделать диалог открытия фала иначе.
 
И бразги летели во все стороны.
 
Останнє редагування:
Спасибо! Правда я ещё немного теряюсь в обилии новых терминов.

в ресурсах я не вижу кнопку для открытия файла.Там видны две кнопки,содержания эбаут и выход,на что и ругается компилятор.
А как же кнопка
#define ID_BUTTON 1001
Именно по нажатию на неё планируется создать диалог открытия файла. Можно конечно разместить её так же в главном меню, но думаю от этого мало что изменится.
Вообще, я делаю программу, где происходит рисование графика по данным, взятым из файла. Открытие файла, зная путь до него и извлечение из него данных в нужные переменные я уже освоил, так же освоил и рисование графика из этих данных. Поэтому что делать после выбора файла я уже знаю, а это остался последний шаг - организовать диалог для получения пути и имени файла.
 
Будем думать,что у вас получается в итоге?
 
Останнє редагування:
Давайте.
В итоге получается, что у меня есть все, кроме диалога открытия файла, в котором можно было бы выбрать любой тхт файл. Чтобы не засорять лишним кодом всю суть проблемы, я выложил код только найденного в интернете диалога. На других сайтах я нашел много высказываний об ошибках в структуре ofn, но сколько я не исправлял, ошибка так и не исчезла.

Ещё на сайте майкрософт я нашел следующую строку: "Начиная с Windows Vista, общий файл Диалог был заменен Общие Пункт Диалог, когда используется для открытия файла. Мы рекомендуем вам использовать общий пункт Dialog API вместо общих File Dialog API в данном случае. ".
Что это значит. Может ли мой пример не работать из-за установленной Windows 7?
 
Останнє редагування:
И бало его много кругом
 
Останнє редагування:
Вот код, который я использовал раньше:
Яким компілятором користуєшся? Visual C++ 2010 Express Edition на твій код вже не матюкається, а Visual C++ Toolkit 2003 ще не розуміє.

Все, розібрався з компіляторами. Зі свого коду видали рядок: ZeroMemory(&ofn, sizeof(ofn));

А, дійшло. Питання в помилці: "undef ined reference to `_GetOpenFileNameA@4'|". Просто мої компілятори не видавали помилок, видавала помилку функція GetOpenFileName (повертала 0, що після розшифрування означало CDERR_INITIALIZATION). От я і подумав... Якщо коротко, то Visual C++ 6.0 SP5 впорався.
 
Яким компілятором користуєшся?
Я использовал среду программирования codeblocks. Теперь я понимаю, что проблема была скорее всего в нем.

Спасибо за ответы, функция в codeblocks'e так и не заработала, пришлось сделать иначе, так что сейчас проблемы уже нет.
 
Господин СИР,як шо бути точнишим,цэ не код ,а бессвязнэ бараньи кругляшки.На трезву голову сегодня подивився на цю *****у и мени соромно стало за вчерашни диалоги с цим "программистом".Нарушена логика,непонимание структуры,яку вин користуэ для создания окна диалога,и навить не разумиэ тих полей ,яки дадуть ему подали скористувати имя потрибного файла и пути к нему.Цэ ж тильки начало,а дали треба цей файл видкрити,считывати данни и формувати линии,або регионы в клиентской частины главного окна.Я никак не разумию,як можно скачивати с интернета кусочки ,собирати в кучу,и выставляти на показ всему миру,навить не подумавши над тим,яку формуэ послидовнить выполнения.
Як можно сформувать послидовнисть,коли в одном сообщении фомувати кнопку меню и тут же вылавливать сигналы вид неи.
Шо мени робити,як шо цэ типичнэ ставлення до процессу твориння всиэи молоди нашей ,як дали жити,чого ждати вид неи ?
 
Сейчас это называется программирование паттернами
 
Какой из меня программист, я просто студент, которому надо было сделать конкретную лабу в краткие сроки с использованием winapi, о существовании которого я неделю назад и не подозревал. Раньше работал только в Turbo c++ от borland, в котором есть vcl и все очень легко и просто.
Как бы все не было криво в коде, даже пример диалога с сайта майкросовта не пошел в этом кодблоксе. Так что я не знаю, что было кривее, мои руки или компилятор, сейчас это уже не важно.
 
Перш за всэ треба увидомити нашэ министерство освити про наявнисть недоделок. Куди подивалась база основ того чи иншего предмета ?
Выпускник чи магистр маэ имети заложенну базу знання для саморозвитку,а нэ кулдиш самопрезначеньня та байдиш освидомленного самосохраненья.
Вай, вай, шо творится.
Валико,треба якимось чином отсортировати байду програмистив,по условию байт-матричной давности 90-х по условию кривизны гипо-языковой состовляющей и хай идуть огороды копать в село ,та убирати наши дворы та улицы писля наших друзив котив та собак.
 
Останнє редагування:
Назад
Зверху Знизу