Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Visual C++/MFC/WTL > форма на MSVC++ 6.0


Автор: eugeniy 23.3.2010, 02:01
Здравствуйте!
Написана программная часть на С по работе с девайсом и работе с мускульной БД в IDE MSVC++ 6.0. Осталось сделать интерфейсную часть проекта. Использую IDE MSVC++ 6.0, нужно сделать форму след. содержания: чтобы выводилось фото человека, его ФИО, дата рождения, курс, факультет, в той же форме должно быть 6 кнопок и таблица, содержащая три столбца))) Прочитал книгу Холзнера Учебный курс Visual C++ 6.0. 14 уроков, но с визуальной средой всё равно проблемы, так как программирую под линукс всё)))
Помогите как и с чего начать?

Автор: borisbn 23.3.2010, 07:30
Посмотри в сторону http://qt.nokia.com
IMHO там нужно не 14 уроков, а 1-2
P.S. Правда "слезть" с него куда сложнее, чем "залезть" smile

Автор: Albor 23.3.2010, 11:06
Создай проект использующий MFC, выбери диалоговое приложение. Получишь макет формы и панель элементов. Дальше интуитивно понятно.

Автор: eugeniy 24.3.2010, 03:10
borisbn:
С QT уже времени мало ковыряться, 2 месяца до сдачи проекта, думал либо в Делфи интерфейсную часть сделать потом в библиотеку собрать и подключить к VC++, либо в VS2005 написать на VB, но думаю что будут проблемы с интеграцией языков, поэтому решил в той же среде делать где и программная часть написана. Только вот дилема получается, либо Win32Application создавать и делать на чистом С используя WinAPI, либо создать проект MFCAppWizard(exe) и юзать С++ и МFC, но С++ не знаю((( соответственно с MFC особо не знаком, да и говорят что очень надо долго ковыряться, чтобы хоть простейшую форму накидать...но с другой стороны и с WinAPI никогда не работал, поэтому получается такая шляпа! где быстрее будет и понятней не известно(

Albor:

Все эти кнопки и прочие элементы я уже накидал на форму и отредактировал, а как теперь с самой проги на С, вызвать обработчик событий по тому или иному действию? (Например, у меня прога делает запрос к БД по определённому критерию, та возвращает результат запроса (например: дата рождения) и помещает в переменную, и как теперь мне тут поступить чтобы эта "дата рождения" отобразилась в интерфейсной части в поле??? ), получается как-то надо обработать это событие? вот здесь и возникает вся суть выше изложенного(

Автор: Earnest 24.3.2010, 09:08
Если используешь MFC, принцип простой. Весь обмен нужно запихать в функцию DoDataExchange в виде DDX-statements, которые связывают поля формы и переменные со значениями. Выглядит примерно так:

void CMyDialog::DoDataExchange (CDataExchange* pDX)
{
   CMyParams* pParms = get...   // здесь ты добываешь указатель на данные, которые нужно читать\писать
   DDX_Text  (pDX, IDC_NAME, pParms->m_sName);  // IDC_NAME - ид-р поля с именем
   ... // остальные переменные в том же духе 
}
В принципе, если ты делал диалог мастером, то он должен был тебе костяк накидать.

Далее, когда нужно прочитать данные с формы, вызываешь UpdateData (TRUE). А когда записать в форму - UpdateData (FALSE).
Скажем, пользователь нажимает кнопку "Запомнить", ты вызываешь в обработчике этой кнопки UpdateData (TRUE), а потом посылаешь заполненную структуру в БД. 

Автор: Albor 24.3.2010, 12:21
Я думаю, что интерфейсная часть должна использовать программу на С, а не наоборот. Раз уж у программы есть взаимодействие с пользователем, то пусть запрос отображаемых данных инициируется формой (пользователем), вызывая функции С-кода. Данные можно разместить в переменных формы, как писала Earnest, а можно и напрямую взаимодействовать с элементами формы, получая соответствующий указатель ф-цией GetDlgItem(ID_ITEM). 

Автор: Alca 25.3.2010, 13:06
http://forum.sources.ru/index.php?showtopic=159560&st=80#
http://code.google.com/p/ullib/downloads/list

Автор: eugeniy 25.3.2010, 23:17
Цитата(Alca @ 25.3.2010,  13:06)
http://forum.sources.ru/index.php?showtopic=159560&st=80#
http://code.google.com/p/ullib/downloads/list


если можно поподробней, что это и для чего?

Автор: Alca 25.3.2010, 23:22
гуишная либа на чистом WinAPI

Автор: eugeniy 26.3.2010, 00:33
Цитата(Earnest @ 24.3.2010,  09:08)
void CMyDialog::DoDataExchange (CDataExchange* pDX)
{
   CMyParams* pParms = get...   // здесь ты добываешь указатель на данные, которые нужно читать\писать
   DDX_Text  (pDX, IDC_NAME, pParms->m_sName);  // IDC_NAME - ид-р поля с именем
   ... // остальные переменные в том же духе 
}

можно здесь поподробней пожалуйста.
Доустим имеется поле "фамилия" - тип static, и поле куда выводиться фамилия - edit box.
фамилия: edit box.
визардом добавил переменную m_surname, Category - control, variable type - CEdit.

как теперь запихать в поле edit box - определённую фамилию, которая допустим содержиться в переменной в коде на С?

Добавлено через 1 минуту и 16 секунд
Цитата(Alca @ 25.3.2010,  23:22)
гуишная либа на чистом WinAPI

да я вот уже не знаю с винапи или с мфц ковыряться? вроде с мфц как-то больше советов дают

Автор: Albor 26.3.2010, 08:08
Код

m_surname.SetWindowText(_T("Иванов"));

Если бы ты визардом добавил переменную типа CString для Edit-контрола, то визард бы сам добавил строчку DDX... и тебе бы нужно было просто присвоить значение полю m_surname и вызвать UpdateData. Лично я предпочитаю первый способ (без DDX), а если на форме много элементов, то пользуюсь указателями на них и переменные в классе не создаю.

Автор: eugeniy 15.4.2010, 00:40
исходный файл на С переделал под visual c++...
но всё равно не получается в edit box вывести содержимое переменных row[4],row[5],row[6],birth,kurs_name[0],fakultet_name[0]
прилагаю к вашему вниманию мой проект
http://ifolder.ru/17299372

если вам не составит труда, посмотрите пожалуйста, что там не так...
сейчас при компиляции пишет:
--------------------Configuration: reader - Win32 Debug--------------------
Compiling...
readerDlg.cpp
c:\program files\microsoft visual studio\vc98\bin\reader\readerdlg.cpp(100) : error C2064: term does not evaluate to a function
c:\program files\microsoft visual studio\vc98\bin\reader\readerdlg.cpp(102) : error C2059: syntax error : '{'
c:\program files\microsoft visual studio\vc98\bin\reader\readerdlg.cpp(102) : error C2143: syntax error : missing ';' before '{'
c:\program files\microsoft visual studio\vc98\bin\reader\readerdlg.cpp(102) : error C2447: missing function header (old-style formal list?)
c:\program files\microsoft visual studio\vc98\bin\reader\readerdlg.cpp(102) : error C2143: syntax error : missing ';' before '}'
c:\program files\microsoft visual studio\vc98\bin\reader\readerdlg.cpp(112) : error C2065: 'birth' : undeclared identifier
c:\program files\microsoft visual studio\vc98\bin\reader\readerdlg.cpp(117) : error C2440: '=' : cannot convert from 'class CReader *' to 'int'
        This conversion requires a reinterpret_cast, a C-style cast or function-style cast
c:\program files\microsoft visual studio\vc98\bin\reader\readerdlg.cpp(118) : error C2227: left of '->Reader_Init' must point to class/struct/union
c:\program files\microsoft visual studio\vc98\bin\reader\readerdlg.cpp(119) : error C2146: syntax error : missing ')' before identifier 'EndDialog'
Error executing cl.exe.

readerDlg.obj - 9 error(s), 0 warning(s)




Автор: Earnest 15.4.2010, 11:04
eugeniy, мало желающих найдется качать твой проект и ковыряться в нем. Если у тебе не компилируется, так приведи конкретный код, который не компилируется. Только бога ради не полный проект. Цени чужое время.

Автор: Albor 15.4.2010, 12:55
По приведенным ошибкам, необходимо проверить фигурные скобки и ; , то бишь - синтаксис.

Автор: eugeniy 15.4.2010, 19:51
все ошибки исправил

Цитата

Если у тебя не компилируется, так приведи конкретный код, который не компилируется.



BOOL CReader::Card_read()
{
    while((row = mysql_fetch_row (res)))
                    {
                                snprintf(kurs,50,"SELECT tech_name FROM kursnames WHERE kurs_id = %s", row[34]);
                                mysql_query(conn,kurs);                            
                                    
                                if (!(res=mysql_store_result(conn)))
                                        //exiterr(2);

                                kurs_name = mysql_fetch_row(res);

                                snprintf(fakultet,100,"SELECT tech_name FROM faculty WHERE faculty_id = %s", row[35]);
                                mysql_query(conn,fakultet);        
                                    
                                if (!(res=mysql_store_result(conn)))
                                    //    exiterr(2);

                                fakultet_name = mysql_fetch_row(res);

                                birth=strtok(row[10], " ");

                                
                                printf("%s %s %s %s %s %s\t",row[4],row[5],row[6],birth,kurs_name[0],fakultet_name[0]);
                                fprintf(file,"%s %s %s %s %s %s\t",row[4],row[5],row[6],birth,kurs_name[0],fakultet_name[0]);
                                
                            
                            printf("\n");
                            fprintf(file, "\n");
                    }
}

как мне с этого кода вывести значение переменных в диалог в поля edit box?

вот вроде бы конкретный код...


Автор: Earnest 16.4.2010, 07:33
После чтения и заполнения переменных диалога, связанных с полями, вызови UpdateData (false).

Автор: eugeniy 16.4.2010, 12:38
Цитата(Earnest @ 16.4.2010,  07:33)
После чтения и заполнения переменных диалога, связанных с полями, вызови UpdateData (false).



Я так полагаю , мне  нужно в файле readerDlg.cpp написать
в функции BOOL CReaderDlg::OnInitDialog()
{
     CDialog::OnInitDialog();
 
     m_surname_CTRL.SetWindowText (вот тут что писать, я же не могу написать просто birth ведь это переменная другого класса, как мне тут поступить, чтобы вывести содержимое birth класса CReader из файла reader_writer.cpp?);

     UpdateData(false);


m_surname - объявленна как контрол. т.е. DDX_Control ( pDX, IDC_SURNAME, m_surname_CTRL);

p.s: Почему когда категорию переменной ставишь value и тип Cstring, т.е. когда обращаешься к свойству объекта, а не к объекту в целом...то при вызове диалога, имя переменной затирается...  smile 

Автор: Albor 16.4.2010, 14:43
eugeniy, тебе нужно получить данные для отображения, для этого нужен механизм взаимодействия между диалогом и кодом, получающим данные. Подключи в диалоге заголовок CReader - a и вызывай его функции, полученные данные копируй в переменные диалога.

Добавлено через 2 минуты и 47 секунд
Цитата(eugeniy @  16.4.2010,  12:38 Найти цитируемый пост)
то при вызове диалога, имя переменной затирается...    

Что ты имеешь ввиду под словом "затирается"?

Автор: eugeniy 16.4.2010, 21:07
Цитата(Albor @ 16.4.2010,  14:43)
eugeniy, тебе нужно получить данные для отображения, для этого нужен механизм взаимодействия между диалогом и кодом, получающим данные. Подключи в диалоге заголовок CReader - a

подключил в диалоге readerDlg.cpp заголовок СReader, путём подключения вверху хэдера reader_writer.h...


Цитата
вызывай его функции, полученные данные копируй в переменные диалога.


можете тут на примере пожалуйста показать, как это делается
так?
BOOL CReaderDlg::OnInitDialog()
{
     CDialog::OnInitDialog();

        BOOL CReader::Card_read()
    {
           m_surname_CTRL.SetWindowText(birth);
           UpdateData(false);
    }
}

или как тогда?

Цитата

Что ты имеешь ввиду под словом "затирается"?




просто когда запускаешь диалог, то поле фамилия имеющая тип CString исчезает.

Автор: Albor 19.4.2010, 12:27
Цитата(eugeniy @  16.4.2010,  21:07 Найти цитируемый пост)
можете тут на примере пожалуйста показать, как это делается
так?

Чтобы показать на примере, нужно хотябы знать интерфейс CReader (кстати, это тип или именованное пространство?). Если это тип,  то в классе диалога нужно создать его объект и через него получать доступ к функциям. Скорее всего, нужно будет расширить функционал функцией, в которую будут передаваться переменные для получения данных, так как представленная Card_read() получает данные во внутренние переменные. Что-то вроде
Код

CReader::GetData(char * fname, char * lname);

Полученное преобразовать к CString и отобразить.
ЗЫ Если ты в классе диалога завёл переменную, определённую как control, то незачем вызывать UpdateData, ведь ты работаешь с объектом напрямую.

Автор: eugeniy 19.4.2010, 21:43
Цитата
Чтобы показать на примере, нужно хотябы знать интерфейс CReader (кстати, это тип или именованное пространство?). Если это тип,  то в классе диалога нужно создать его объект и через него получать доступ к функциям.

Да CReader - это тип.
Я создал объект класса CReader
Код
m_reader = new CReader;

и про инициализировал БД mysql
Код
if(!(m_reader->Reader_Init()))
          EndDialog(0);



Цитата
Скорее всего, нужно будет расширить функционал функцией, в которую будут передаваться переменные для получения данных, так как представленная Card_read() получает данные во внутренние переменные.Что-то вроде
Код

CReader::GetData(char * fname, char * lname);

Полученное преобразовать к CString и отобразить.

можете показать на примере как это примерно должно выглядеть?




Цитата
ЗЫ Если ты в классе диалога завёл переменную, определённую как control, то незачем вызывать UpdateData, ведь ты работаешь с объектом напрямую.

ну в принципе верно, я ведь не с отдельным свойством объекта работаю, а как с ним целым.

Автор: Albor 20.4.2010, 11:07
Цитата(eugeniy @  19.4.2010,  21:43 Найти цитируемый пост)
можете показать на примере как это примерно должно выглядеть

Примерно так:
Код

void CReader::GetData(char * & pFakultet, char * & pBirth, char ** & pRow, int & sizeRow)
{
   Card_read(); // читаем данные
// копируем указатели
   pFakultet=fakultet_name;
   pBirth = birth;
   pRow = row;
// получаем размер, определённый для массива row, чтобы в диалоге знать сколько в нём элементов
   sizeRow = rowSize;
}

Вызвав эту функцию из диалога,  переданные в неё указатели будут указывать на нужные данные. А для отображения вызываешь m_surname_CTRL.SetWindowText(pBirth);
Принцип понятен? Тебе, конечно, нужно будет подправить под свои нужды. Можно скопировать данные, а не получать указатели, чтобы не "вмешиваться" во внутреннее устройство CReader, но это уже как тебе больше нравится smile . 

Автор: eugeniy 20.4.2010, 12:21
Цитата(Albor @ 20.4.2010,  11:07)
Примерно так:
Код

void CReader::GetData(char * & pFakultet, char * & pBirth, char ** & pRow, int & sizeRow)
{
   Card_read(); // читаем данные
// копируем указатели
   pFakultet=fakultet_name;
   pBirth = birth;
   pRow = row;
// получаем размер, определённый для массива row, чтобы в диалоге знать сколько в нём элементов
   sizeRow = rowSize;
}

Вызвав эту функцию из диалога,  переданные в неё указатели будут указывать на нужные данные. А для отображения вызываешь m_surname_CTRL.SetWindowText(pBirth);
Принцип понятен? Тебе, конечно, нужно будет подправить под свои нужды. Можно скопировать данные, а не получать указатели, чтобы не "вмешиваться" во внутреннее устройство CReader, но это уже как тебе больше нравится smile .

Значит получилось так, функция описана в reader_writer.cpp
Код

void CReader::GetData (char ** & pFakultet, char * & pBirth, char ** & pKurs, char ** & pRow, int & sizeRow)
{
    CReader::Card_read();
    pFakultet=fakultet_name;
    pBirth=birth;
    pKurs=kurs_name;
    pRow=row;
    sizeRow=rowSize;
}


Предварительно в файле reader_writer.h прописал ещё один метод класса:
Код
void GetData (char ** & pFakultet, char * & pBirth, char ** & pKurs, char ** & pRow, int & sizeRow);


затем он ругался, что не понимает идетификатор rowSize, объявил его как целый тип, и обнулил.

После этих манипуляций вызвал в BOOL CReaderDlg::OnInitDialog()
Код
void GetData();


и вот затем если я хочу вызывать функцию для отображения то бишь
Код
m_birthday_CTRL.SetWindowText(pBirth);


то компилятор пишет:

--------------------Configuration: reader - Win32 Debug--------------------
Compiling...
readerDlg.cpp
c:\program files\microsoft visual studio\vc98\bin\reader(2)\reader\readerdlg.cpp(154) : error C2039: 'SetWindowTextA' : is not a member of 'CString'
        c:\program files\microsoft visual studio\vc98\mfc\include\afx.h(368) : see declaration of 'CString'
c:\program files\microsoft visual studio\vc98\bin\reader(2)\reader\readerdlg.cpp(154) : error C2065: 'pBirth' : undeclared identifier
Error executing cl.exe.

readerDlg.obj - 2 error(s), 0 warning(s)

Автор: Albor 20.4.2010, 12:27
Так m_birthday_CTRL имеет тип CString?

Добавлено @ 12:33
Кстати, и rowSize зря ты обнулил. Где-то ж у тебя определяется размер массива row, вот его-то и нужно использовать. Именно это я и имел ввиду под rowSize.

Добавлено @ 12:35
А fakultet_name это массив строк?

Автор: eugeniy 20.4.2010, 12:40
Цитата(Albor @ 20.4.2010,  12:27)
Так m_birthday_CTRL имеет тип CString?


да что-то я тупанул)))
исправил на CEdit теперь пишет, что pBirth не определена

Добавлено @ 12:33
Цитата
Кстати, и rowSize зря ты обнулил. Где-то ж у тебя определяется размер массива row, вот его-то и нужно использовать.


у меня row, объвлен как MYSQL_ROW row;
MYSQL_ROW - это указатель на указатель на символ ) т.е. - это указатель не на строку, а на массив строк.
То есть я получаю функцией mysql_fetch_row в переменную row целый массив строк.





Автор: Albor 20.4.2010, 12:44
Цитата(eugeniy @  20.4.2010,  12:40 Найти цитируемый пост)
pBirth не определена

Так нужно определить все переменные перед вызовом функции. 

Автор: eugeniy 20.4.2010, 12:44
Цитата(Albor @ 20.4.2010,  12:27)
Так m_birthday_CTRL имеет тип CString?

Добавлено @ 12:33
Кстати, и rowSize зря ты обнулил. Где-то ж у тебя определяется размер массива row, вот его-то и нужно использовать. Именно это я и имел ввиду под rowSize.


Добавлено @ 12:35
Цитата
А fakultet_name это массив строк?

да, также массив строк, аналогично и kurs_name

Добавлено через 4 минуты и 40 секунд
Цитата(Albor @ 20.4.2010,  12:44)
Цитата(eugeniy @  20.4.2010,  12:40 Найти цитируемый пост)
pBirth не определена

Так нужно определить все переменные перед вызовом функции.

т.е. определить в данных класса CReader, также как и др. переменные?

Автор: Albor 20.4.2010, 12:55
 
Цитата(eugeniy @  20.4.2010,  12:44 Найти цитируемый пост)
да, также массив строк, аналогично и kurs_name 

Понятно, у тебя получается в CReader набор записей. Тогда нужно получать размеры для каждого массива, иначе как ты будешь обрабатывать указатели. Или решить вопрос по другому: обратиться к CReader с "просьбой" вернуть определённую запись, скажем, по индексу. Всё-таки очень трудно что-то разумное подсказать, не имея более полной информации.

Автор: eugeniy 20.4.2010, 13:01
Цитата(Albor @ 20.4.2010,  12:55)

Или решить вопрос по другому: обратиться к CReader с "просьбой" вернуть определённую запись, скажем, по индексу.

это так что ли?

CWnd* wnd=GetDlgItem(IDC_BIRTHDAY);
wnd->SetWindowText(pBirth);


Цитата
Всё-таки очень трудно что-то разумное подсказать, не имея более полной информации.


дак я вам могу её предоставить, ежели требуется...

Автор: Albor 20.4.2010, 13:03
Цитата(eugeniy @  20.4.2010,  12:44 Найти цитируемый пост)
т.е. определить в данных класса CReader, также как и др. переменные? 

Нет, определить в диалоге перед вызовом функции объекта CReader. Переменные ведь передаются по ссылке, значит, прежде чем их "скормить" в функцию, они должны существовать.

Добавлено через 5 минут и 26 секунд
Цитата(eugeniy @  20.4.2010,  13:01 Найти цитируемый пост)
это так что ли?

Это нормально для установки текста в контроле с id IDC_BIRTHDAY, только pBirth должен указывать на массив символов с завершающим нулём (с-строку), а для этого pBirth нужно скормить функции GetData() и, после того как она отработает устанавливать текст в контроле.

Добавлено через 7 минут и 34 секунды
Цитата(eugeniy @  20.4.2010,  13:01 Найти цитируемый пост)
дак я вам могу её предоставить, ежели требуется...

Покажи хеадер класса CReader.

Автор: eugeniy 20.4.2010, 13:18
Цитата(Albor @ 20.4.2010,  13:03)
Цитата
Покажи хеадер класса CReader.

// reader_writer.h  обьявление
///////////////////////////////////////////////////////////////////////////
#if _MSC_VER > 1000
#pragma once
#include <winsock.h>
#include "mysql.h"
#include "mwrf32.h"


    class CReader
{
    public:
    CReader(void);

    ~CReader(void);
    
    ////////////////////////////////////////////////////////////////////////
    //  Данные класса

    MYSQL* conn;      
    MYSQL_RES *res;
    MYSQL_ROW row;
    MYSQL_ROW fakultet_name;
    MYSQL_ROW kurs_name;

    int ver,t;
    int st,k,j,s;
    char *kurs, *fakultet;
    char *query;
    char *birth;
    char a[3];
    int rowSize;
    unsigned char *stud_id;
    unsigned char i;

    unsigned char size;
    unsigned char data[50];
    unsigned long sn_card;    
    unsigned long old_sn_card;

    unsigned char key[6]; 

    HANDLE dev;
    FILE *file;
    FILE *fp;

    ///////////////////////////////////////////////////////////////////
    //  Методы класса
    // -- инициализация базы данных
    BOOL Reader_Init();  
    // -- проверка серийного номера
    BOOL Read_serial_number();
    // -- считывание карты
    BOOL Card_read();
    // -- закрытие устройства
    BOOL Close_device();
    // -- закрытие БД и файлов
    BOOL Close_mysql_and_file();
    // -- получение данных ;)
    void GetData(char ** & pFakultet,char * & pBirth,char ** & pKurs,char ** & pRow, int & sizeRow);

};
#endif // _MSC_VER > 1000

Автор: eugeniy 20.4.2010, 14:18
Цитата(Albor @ 20.4.2010,  13:03)
Цитата
Нет, определить в диалоге перед вызовом функции объекта CReader. Переменные ведь передаются по ссылке, значит, прежде чем их "скормить" в функцию, они должны существовать.


можно пожалуйста показать на примере?

или так?

в файле readerDlg.h
Код
CDialog* pBirth;


затем в readerDlg.cpp

Код
pBirth = new CDialog


Цитата
а для этого pBirth нужно скормить функции GetData() и, после того как она отработает устанавливать текст в контроле.


а каким образом скормить?

на данный момент у меня в диалоге:
Код
BOOL CReaderDlg::OnInitDialog()
{
    CDialog::OnInitDialog();
       SetTimer(ID_TIMER_1,300000,0);
    
    m_reader = new CReader;            //создание объекта класса CReader
    if(!(m_reader->Reader_Init()))    // инициализация БД
          EndDialog(0);
    
    if(!(m_reader->Read_serial_number()))    //проверка серийного номера карты
          EndDialog(0);
    
    void GetData();        //получение данных

    m_birthday_CTRL.SetWindowText(pBirth);


Автор: Albor 20.4.2010, 15:16
Можно функцию получения данных оформить так:
Код

void CReader::GetData(MYSQL_ROW & fakultet_row, MYSQL_ROW & kurs_row, MYSQL_ROW & rows)
{
  Card_read();
  fakultet_row = fakultet_name;
  kurs_row = kurs_name;
  rows = row;
}

К сожалению, я не работал с MYSQL и мне тяжело ориентироваиться в её типах, но, проанализировав приведенный код и бегло просмотрев инфу по MYSQL думаю, что можно сделать так как показано выше. При отображении в классе диалога использовать индекс колонки таблицы б.д.
Код

GetDlgItem(IDC_BIRTHDAY)->SetWindowText(rows[10]);

Автор: Albor 20.4.2010, 16:55
eugeniy, на будущее: если функция требует параметр типа char *, то будет неправильным объявить переменную как CDialog* pBirth и пытаться передать её в функцию. Переменная должна соответствовать требуемому типу: char * pBirth; "Скормить" - это означает передать smile . Целью вызова функции GetData является получение указателей на данные, поэтому вызов её без параметров, как в твоём примере, недопустим. То есть схема такая: объявляем нужные указатели в диалоге -> передаём их в функцию GetData (она присваивает им нужные значения) -> после, используем указатели для отображения в контролах.
PS Не обратил внимания сразу: в OnInitDialog ты сделал объявление функции GetData, а не её вызов. Ты ведь создал объект CReader, так и вызывай для него m_reader->GetData(параметры...).

Автор: eugeniy 21.4.2010, 01:32
Цитата(Albor @ 20.4.2010,  16:55)
eugeniy, на будущее: если функция требует параметр типа char *, то будет неправильным объявить переменную как CDialog* pBirth и пытаться передать её в функцию. Переменная должна соответствовать требуемому типу: char * pBirth; "Скормить" - это означает передать smile . Целью вызова функции GetData является получение указателей на данные, поэтому вызов её без параметров, как в твоём примере, недопустим. То есть схема такая: объявляем нужные указатели в диалоге -> передаём их в функцию GetData (она присваивает им нужные значения) -> после, используем указатели для отображения в контролах.
PS Не обратил внимания сразу: в OnInitDialog ты сделал объявление функции GetData, а не её вызов. Ты ведь создал объект CReader, так и вызывай для него m_reader->GetData(параметры...).

Понятно щас поробую, а такой вариант разве не прокатит?

1)в reader_writer.h объявить метод класса CReader вот так
Код
void GetData();


2)потом сделать само тело функции в reader_writer.cpp
Код
void CReader::GetData()
{
    CReader::Card_read();
}


3)затем в readerDlg.cpp
Код
m_reader = new CReader;            //создание объекта класса CReader
    if(!(m_reader->Reader_Init()))    // инициализация БД
          EndDialog(0);

if(m_reader->Card_read()){
        m_reader->GetData();        //получение данных
        m_birthday_CTRL.SetWindowText(m_reader->birth);
        UpdateData(false);
    }
    else
        EndDialog(0);


строчка m_birthday_CTRL.SetWindowText(m_reader->birth); означает, что мы выводим в контрол m_birthday_CTRL, содержимое переменной birth, ведь объект m_reader класса CReader и сама birth описана как данные класса CReader, т.е. вроде как правильно ссылаемся, но ничерта не работает...

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




Автор: Albor 21.4.2010, 11:41
Цитата(eugeniy @  21.4.2010,  01:32 Найти цитируемый пост)
Понятно щас поробую, а такой вариант разве не прокатит?

Да должен прокатить раз все переменные в открытом доступе, только GetData в таком варианте не нужна   - вместо неё вызвать Card_read() и всё. А что в отладчике вот в этом месте:
Код

m_birthday_CTRL.SetWindowText(m_reader->birth);

Конкретно - что по адресу m_reader->birth?

Добавлено через 11 минут и 24 секунды
Знаешь что ещё попробуй, перенеси код из OnInitDialog куда-нибудь в другое место, например, добавь кнопку на форму, добавь обработчик нажатия и вставь код туда. Кто знает что ты намудрил с переменными для контрола, может при инициализации текст просто затирается.

Автор: eugeniy 22.4.2010, 01:15
Цитата
Да должен прокатить раз все переменные в открытом доступе, только GetData в таком варианте не нужна   - вместо неё вызвать Card_read() и всё. А что в отладчике вот в этом месте:
Код

m_birthday_CTRL.SetWindowText(m_reader->birth);

Конкретно - что по адресу m_reader->birth?

Там вообщем пусто было, т.е. просто в поле ничего не записывалось....в дебаге посмотрел где валится, нашёл ошибку, исправил

После этого, всё успешно вывилось содержимое birth в контрол, только вот срабатывает как-то криво, когда карточка лежит на ридере то выводит день рождение, а когда запустил диалог и потом поднёс карточку уже ничерта не выводит, ну это наверно уже приблуды visual c++.
хотя когда изначальный код был, то он выводил независимо есть карточка в данный момент на ридере или же потом поднесли, , надо будет с этим позже разобраться....

Только вот переменные объвленные как массив строк не выводятся row[4], row[5] и т.д....в дебаге посмотрел, на строке
Код
m_surname_CTRL.SetWindowText(m_reader->row[4]);

пишет: Unhandled exception at 0x0040309f in reader.exe: 0xC0000005: Access violation reading location 0x00000010.




Автор: Albor 22.4.2010, 08:22
Цитата(eugeniy @  22.4.2010,  01:15 Найти цитируемый пост)
Только вот переменные объвленные как массив строк не выводятся row[4], row[5] и т.д....в дебаге посмотрел, на строке

Так в Card_read() в row ни чего не заносится, может ты заполняешь эту переменную где-то в другом месте? Кстати, MYSQL_ROW не совсем массив строк, как я понял, наверное оператор [] у него возвращает строку.

Автор: eugeniy 23.4.2010, 01:40
Цитата
Так в Card_read() в row ни чего не заносится, может ты заполняешь эту переменную где-то в другом месте?


Нет всё заносится в этом методе Card_read() во все переменные row[4], row[5] и т.д....

Цитата
Кстати, MYSQL_ROW не совсем массив строк, как я понял, наверное оператор [] у него возвращает строку.


я функцией mysql_fetch_row в переменную row заношу целый массив строк, а уже потом обрезаю этот массив как мне нужно.т.е если я сделал выборку из трех столбцов то результат у меня соответственно будет находиться в row[0], row[1], row[2]. Таким образом получается как вы и говорите оператор [] возвращает конкретную строку.
Если верить C API для MySQL,то

MYSQL_ROW - Является ``типобезопасным'' представлением данных одной строки. В настоящее время этот тип реализован как массив строк с фиксированным количеством байтов (их нельзя трактовать как строки с нулевым символом в конце, если величины полей могут содержать двоичные данные, поскольку они могут содержать ноль байтов). Строки можно получить вызовом функции mysql_fetch_row(). 

Теперь по поводу вывода в контролы диалога этих строк, я их вывел таким путём
1) завёл в классе CReader переменные типа CString, также их продублировал в CReaderDlg
Код
CString Imya;
CString Familiya;

2) затем в Card_read, где я извлёк данные из mysql функцией mysql_fetch_row() и сразу после этого перепресвоил значения переменных row[4] и т.д. этим переменным.
Код
 Imya = row[4];
Familiya= row[5];

и т.д.
3)а потом уже в CReader::OnInitDialog()
после вызова Card_read() делаю
Код
m_surname_CTRL.SetWindowText(m_reader->Familiya);

4) в контроле диалога получаю, вместо вывода фамилии вопросительные знаки ???????

смотрел в дебагере, как только захожу в цикл    while((row = mysql_fetch_row (res)))
то сразу все переменные row заполняются знаками вопросами.

Дата вывелась т.к. там цифры, тут видимо какой-то баг с кодировкой, не хочет кириллицу выводить(
Видимо тут уже Винда комедит, можете что-нибудь подсказать по этому поводу???






Автор: Albor 23.4.2010, 08:00
Цитата(eugeniy @  23.4.2010,  01:40 Найти цитируемый пост)
тут видимо какой-то баг с кодировкой, не хочет кириллицу выводить(
Видимо тут уже Винда комедит, можете что-нибудь подсказать по этому поводу???

Попробуй сделать:
Код

Imya = _T(row[4]);
Familiya= _T(row[5]);

Автор: eugeniy 24.4.2010, 13:19
Цитата(Albor @ 23.4.2010,  08:00)
Цитата(eugeniy @  23.4.2010,  01:40 Найти цитируемый пост)
тут видимо какой-то баг с кодировкой, не хочет кириллицу выводить(
Видимо тут уже Винда комедит, можете что-нибудь подсказать по этому поводу???

Попробуй сделать:
Код

Imya = _T(row[4]);
Familiya= _T(row[5]);

Неа не помогает, просто выводит вместо русских букв, знаки вопроса, тут наверно проблема в кодировки. А вы как считаете?

Автор: eugeniy 24.4.2010, 21:11
по ходу дела данные выбираются в кодировке latin1, которая стоит в БД по дефолту, поэтому и выводится знаками вопроса "?????"
У меня раньше такая проблема была, када я код писал на С, при выводе на консоль получались кракозябрики, проблема решилась после установки соединения с БД, вызовом команды 
Код
mysql_query("SET NAMES 'cp866'");
. т.е. выводом данных в досовской кодировке.
После этого все данные отображались корректно, русскими буквами

Но применив эту же операцию к нынешнему случаю, только вместо cp866 используя cp1251 ничего не произошло.



Автор: Albor 26.4.2010, 09:55
Не знаю, если бы кодировка - были бы кракозябры, а так похоже на 2-х байтные символы. Посмотри что копируется в объект CString, если исходная строка через байт, то разбирайся с Unicode.

Автор: eugeniy 27.4.2010, 20:39
Цитата(Albor @ 26.4.2010,  09:55)
Не знаю, если бы кодировка - были бы кракозябры, а так похоже на 2-х байтные символы. Посмотри что копируется в объект CString, если исходная строка через байт, то разбирайся с Unicode.

Да, уже разобрался, проблема была на самом деле в кодировки, по дефолту мускульный сервер использует кодировку latin1, а она именно и выводит всю кириллицу в виде знаков вопроса, причём каждая буква - это один знак вопроса.т.е. он всё время возвращал в своей кодировке.
Пришлось заюзать функцию mysql_set_character_set(), которая возвращает все значения, через это соединение в нужной мне кодировки автоматически. Таким образом все поля вывелись благополучно)))
Только вот теперь не знаю как фото из БД выцепить,и также в интерфейс диалога запихать? Думаю аналогичным образом не прокатит так сделать, тут ведь уже не текстовая информация...Каким образом можно сделать, не подскажите?

Спасибо.

Автор: Albor 27.4.2010, 21:13
Есть элемент в тулбоксе, называется Picture Control. В его свойствах определи тип "иконка" или "битмап"(что нужно) и размещай в нём картинку.

Автор: eugeniy 28.4.2010, 15:00
Цитата(Albor @ 27.4.2010,  21:13)
Есть элемент в тулбоксе, называется Picture Control. В его свойствах определи тип "иконка" или "битмап"(что нужно) и размещай в нём картинку.

Это то я уже сделал (битмап), а какие классы, методы нужны для работы с картинкой?
Просто с текстом был гемор полный, а тут по моему, как я полагаю, всё ещё хуже обстоит(

Автор: Albor 28.4.2010, 15:32
У CStatic (именно такого типа будет переменная для Picture Control, только не забудь изменить идентификатор для картинки, а то не сможешь добавить переменную)  есть ф-ция SetBitmap(). Понадобится CBitmap. Как получить CBitmap из данных в твоей базе не подскажу - не знаю. Думаю что не сложнее, чем со строками.

Автор: eugeniy 28.4.2010, 23:43
Цитата(Albor @ 28.4.2010,  15:32)
У CStatic (именно такого типа будет переменная для Picture Control, только не забудь изменить идентификатор для картинки, а то не сможешь добавить переменную)  есть ф-ция SetBitmap(). Понадобится CBitmap. Как получить CBitmap из данных в твоей базе не подскажу - не знаю. Думаю что не сложнее, чем со строками.

Поменял ID картинки, на IDC_PHOTO, сделал переменную типа CStatic.

А как этими SetBitmap и CBitmap пользоваться?
Например, если просто тупо из файла вставить картинку в диалог?

Автор: eugeniy 29.4.2010, 02:24
Я так понял, если делаешь Bitmap тип, то только можно работать с картинками формата bmp?
Других вариантов не остаётся? А как же jpg, gif, png???

Автор: eugeniy 4.5.2010, 23:33
поработал с классом CBitmap, там только две функции поюзал, это LoadBitmap и SetBitmap, получается и вправду этот класс может работать только с картинками формата bmp.
А если у меня на фтп-сервере картинки в jpg и png хранятся, то как тогда тут быть? Получается какие-то сторонние библиотеки нужно подключать?

Автор: eugeniy 7.5.2010, 00:51
Albor, вы где?
Какими средствами можно обойтись в mfc для решения данной проблемы?
Может есть уже готовое решение, и велосипед не нужно изобретать?

Автор: Albor 7.5.2010, 14:22
В MFC, по-моему нет, во всяком случае я не знаю. Не найду никак ссылку, автор - Виталий Рычков (WinMain), показывал как это можно сделать, по-моему, используя ATL. Найду ссылку на статью разве что, а так помочь не могу. 

Автор: eugeniy 10.5.2010, 23:29
Albor, вы где?
Какими средствами можно обойтись в mfc для решения данной проблемы?
Может есть уже готовое решение, и велосипед не нужно изобретать?

Автор: Albor 11.5.2010, 12:32
Смотри пример http://www.codeproject.com/KB/buttons/CKbcButton.aspx. В коде найдёшь как загрузить разные типы картинок.

Автор: eugeniy 14.5.2010, 02:18
Цитата(Albor @ 11.5.2010,  12:32)
Смотри пример http://www.codeproject.com/KB/buttons/CKbcButton.aspx. В коде найдёшь как загрузить разные типы картинок.

Спасибо за ссылочку.
Вообщем сделал я по этому примеру вывод картинки.
Там во-первых этот класс CPicture работает только с bmp, gif, jpeg, а png не поддерживает, что уже мне не подходит.
Во-вторых мне удалось вывести картинку жпег прямо на диалоге, используя функцию BOOL OnEraseBkgnd(CDC* pDC).
в элемент picture  control, так и не удалось вывести(

поработал с классом CImage, он уже со всеми форматами умеет работать)
вот кусок кода, отвечающий за загрузку картинки и вывод её в элемент picture control.
Код

CStatic m_photo;
CImage image;
image.Load("670.jpg");

HBITMAP hbmp=m_photo.GetBitmap();
CBitmap* bmp=CBitmap::FromHandle(hbmp);
CDC dc;
dc.CreateCompatibleDC(NULL);
CBitmap* old=dc.SelectObject(bmp);
m_photo=SetBitmap(image);

int x=0; 
int y=0;

image.AlphaBlend(dc,x,y,0xff,AC_SRC_OVER);

dc.SelectObject(old);

m_photo.Invalidate();



но он мне рисует только рамку картинки исходных размеров, а саму картинку в диалоге не прорисовывает, делал в OnInitDialog.
не знаю почему, уже всё перепробывал(

Потом сделал в функции BOOL OnEraseBkgnd(CDC* pDC). На что он мне вывел картинку исходных размеров, но при этом убрал задний фон(
Как мне теперь сжать картинку до нужных мне размеров? и вернуть на место задний фон?

прилагаю два скрина, один - результат работы BOOL OnEraseBkgnd(CDC* pDC), а второй - как должно быть.

http://ifolder.ru/17699882

Автор: Albor 14.5.2010, 09:27
Цитата(eugeniy @  14.5.2010,  02:18 Найти цитируемый пост)
Как мне теперь сжать картинку до нужных мне размеров? и вернуть на место задний фон?

Попробуй использовать другой вариант функции вывода 
Код

BOOL AlphaBlend(
   HDC hDestDC,
   int xDest,
   int yDest,
   int nDestWidth,
   int nDestHeight,
   int xSrc,
   int ySrc,
   int nSrcWidth,
   int nSrcHeight,
   BYTE bSrcAlpha = 0xff,
   BYTE bBlendOp = AC_SRC_OVER 
);


Автор: Albor 14.5.2010, 10:56
Цитата(eugeniy @  14.5.2010,  02:18 Найти цитируемый пост)
но он мне рисует только рамку картинки исходных размеров, а саму картинку в диалоге не прорисовывает, делал в OnInitDialog.

А объект CImage создавался в OnInitDialog? Если да, то объяви его как член класса диалог. А так - это временный объект, уничтожаемый по завершению OnInitDialog.
m_photo=SetBitmap(image); не правильно
m_photo.SetBitmap((HBITMAP)image); так должно быть

Автор: eugeniy 15.5.2010, 00:38
Цитата(Albor @ 14.5.2010,  09:27)
Цитата(eugeniy @  14.5.2010,  02:18 Найти цитируемый пост)
Как мне теперь сжать картинку до нужных мне размеров? и вернуть на место задний фон?

Попробуй использовать другой вариант функции вывода 
Код

BOOL AlphaBlend(
   HDC hDestDC,
   int xDest,
   int yDest,
   int nDestWidth,
   int nDestHeight,
   int xSrc,
   int ySrc,
   int nSrcWidth,
   int nSrcHeight,
   BYTE bSrcAlpha = 0xff,
   BYTE bBlendOp = AC_SRC_OVER 
);


немного не понял как её прикрутить(AlphaBlend), так что ли?

Код

CImage image;
image.Load("670.jpg");
int w = image.GetWidth();
int h = image.GetHeight();

..........


image.AlphaBlend(dc,100,100,200,200,100,100,w,h,0xff,AC_SRC_OVER);

........


всё это в функции OnInitDialog.

Добавлено через 5 минут и 12 секунд
Цитата
А объект CImage создавался в OnInitDialog? 

Да создавался в OnInitDialog

Цитата
Если да, то объяви его как член класса диалог.

Всмысле в хэдере? если да, то объявил вот так
Код

class CReaderDlg : public CDialog
{
public:
CImage image;




Автор: Albor 17.5.2010, 17:42
Вот обещанная http://devels.ru/index.php?what=art&p=417. Там же можно скачать пример с использованием MFC.

Автор: eugeniy 17.5.2010, 21:07
Цитата(Albor @ 17.5.2010,  17:42)
Вот обещанная http://devels.ru/index.php?what=art&p=417. Там же можно скачать пример с использованием MFC.

Уже сделал с использование класса CImage.
Получилось примерно так.
Код
BOOL CReaderDlg::OnEraseBkgnd(CDC* pDC)
{    
    // draw back ground

    CRect rect;
    GetClientRect(&rect);
    CBrush brush;
    DWORD color = GetSysColor(COLOR_3DFACE);
    brush.CreateSolidBrush(color);
    pDC->FillRect(&rect,&brush);

    CImage image,image2;
    image.Load("228.png");
    int w = image.GetWidth();
       int h = image.GetHeight();     
    int tnh=200;
    int tnw=200*w/h;
    int bpp=image.GetBPP();
    image2.Create(tnw,tnh,bpp);
    HDC h2=image2.GetDC();
    SetStretchBltMode(h2,HALFTONE);
    image.StretchBlt(h2,0,0,tnw,tnh,SRCCOPY);
    image2.ReleaseDC();
    HBITMAP        hbmp = m_photo.GetBitmap();
    CBitmap       *bmp = CBitmap::FromHandle(hbmp);
    CDC            dc;
    dc.CreateCompatibleDC(NULL);
    CBitmap*    old = dc.SelectObject(bmp);
    m_photo.SetBitmap((HBITMAP)image2);
    dc.SelectObject(old);
    m_photo.Invalidate();    

    return TRUE;    
}


только вот не пойму как такое проделать.
А если у меня вот такая ситуация. есть переменная CString Foto, переменная Foto в свою очередь присваивается каждый раз значение row[20] (результат выборки из таблицы БД Mysql), в которой хранится, например, 1.jpg

т.е. получается Foto = 1.jpg
Как мне в функции загрузки картинки прописать параметр?
Image.Load(LPCTSTR(Foto)) и Image.Load(Foto(GetBuffer())) пробовал не работает, падает с ошибкой.(((

Автор: Albor 18.5.2010, 10:06
Цитата(eugeniy @  17.5.2010,  21:07 Найти цитируемый пост)
 Image.Load(Foto(GetBuffer())) 

Код

Foto.GetBuffer();
....
 Foto.ReleaseBuffer();// иначе дальше не сможешь изменять переменную

Автор: eugeniy 18.5.2010, 23:41
Цитата(Albor @ 18.5.2010,  10:06)
Цитата(eugeniy @  17.5.2010,  21:07 Найти цитируемый пост)
 Image.Load(Foto(GetBuffer())) 

Код

Foto.GetBuffer();
....
 Foto.ReleaseBuffer();// иначе дальше не сможешь изменять переменную

Вообщем ситуация такая:
Когда делаю выборку данных из mysql:
Код
BOOL CReader::Card_read()
{
.........
while((row = mysql_fetch_row (res)))
                    {
                                
                                snprintf(kurs,50,"SELECT tech_name FROM kursnames WHERE kurs_id = %s", row[34]);
                                mysql_query(conn,kurs);                            
                                    
                                if (!(res=mysql_store_result(conn))){
                                            AfxMessageBox("ERROR(2): error_result\n");
                                            return FALSE;
                                }
                                        
                                kurs_name = mysql_fetch_row(res);

                                snprintf(fakultet,100,"SELECT tech_name FROM faculty WHERE faculty_id = %s", row[35]);
                                mysql_query(conn,fakultet);        
                                    
                                if (!(res=mysql_store_result(conn))){
                                            AfxMessageBox("ERROR(3): error_result\n");
                                            return FALSE;
                                }

                                fakultet_name = mysql_fetch_row(res);
    
                                birth=strtok(row[10], " ");
                            
                                
                                printf("%s %s %s %s %s %s\t",row[4],row[5],row[6],row[20],birth,kurs_name[0],fakultet_name[0]);
                                fprintf(file,"%s %s %s %s %s %s\t",row[4],row[5],row[6],birth,kurs_name[0],fakultet_name[0]);
                                    
                                Familiya = row[4];
                                Imya = row[5];
                                Ot4estvo = row[6];
                                Kurs = kurs_name[0];
                                Fakultet = fakultet_name[0];
                                Foto = row[20];
}

то в дебаггере вижу, что в foto попало нужно значение, например, 1234.jpg.

Потом же после выборки я попадаю сюда:
Код

void CReaderDlg::OnTimer(UINT nIDEvent)
{
    CDialog::OnTimer(nIDEvent);

    m_reader = new CReader;
    if(!(m_reader->Reader_Init()))
        EndDialog(0);
    
        if(!(m_reader->Read_serial_number()))
            EndDialog(0);

вот сюда->    if(m_reader->Card_read())
        {
            m_birthday_CTRL.SetWindowText(m_reader->birth);    
            m_surname_CTRL.SetWindowText(m_reader->Familiya);
            m_name_CTRL.SetWindowText(m_reader->Imya);
            m_patronymic_CTRL.SetWindowText(m_reader->Ot4estvo);
            m_kurs_CTRL.SetWindowText(m_reader->Kurs);
            m_fakultet_CTRL.SetWindowText(m_reader->Fakultet);
            UpdateData(FALSE);
        }
        else
            EndDialog(0);


}

и сразу же как-только я вхожу в функцию void CReaderDlg::OnTimer(UINT nIDEvent) , то сразу переменная foto становится пустая
Код

foto = "";


сделал в функции BOOL CReaderDlg::OnEraseBkgnd(CDC* pDC) проверку на пустоту, чтобы не валился код.
Код

BOOL CReaderDlg::OnEraseBkgnd(CDC* pDC)
{    
    CRect rect;
    GetClientRect(&rect);
    CBrush brush;
    DWORD color = GetSysColor(COLOR_3DFACE);
    brush.CreateSolidBrush(color);
    pDC->FillRect(&rect,&brush);

    CImage image,image2;
    
    
        
    if (strcmp(Foto, "") == 0)
        return false;

    image.Load(LPCTSTR(Foto));
    int w = image.GetWidth();
        int h = image.GetHeight();     
    int tnh = 200;
    int tnw = 200 * w / h;
    int bpp = image.GetBPP();
    
    image2.Create(tnw,tnh,bpp);
    HDC h2=image2.GetDC();

    SetStretchBltMode(h2,HALFTONE);
    image.StretchBlt(h2,0,0,tnw,tnh,SRCCOPY);
    image2.ReleaseDC();

    HBITMAP        hbmp = m_photo.GetBitmap();
    CBitmap       *bmp = CBitmap::FromHandle(hbmp);
    CDC            dc;
    dc.CreateCompatibleDC(NULL);
    CBitmap*    old = dc.SelectObject(bmp);
    m_photo.SetBitmap((HBITMAP)image2);

    dc.SelectObject(old);
    m_photo.Invalidate();    

    return TRUE;    
}


такое ощущение, что надо что-то поменять местами.
может,
Код

image.Load(LPCTSTR(Foto));


нужно в другое место запихать?

не пойму никак, в чём дело.
Да, для справки у меня переменная foto объявлена два раза, сначала в
Код

class CReaderDlg : public CDialog
{
// Construction
public:
    CReaderDlg(CWnd* pParent = NULL);
CString Foto;
}



потом в
Код

class CReader
{
    public:
    CReader(void);
    ~CReader(void);
CString Foto;
}

Автор: Albor 19.5.2010, 09:51
Если переменная с таким именем есть и в классе CReader и в классе CReaderDlg, то это совершенно разные переменные. CString на пустую строку проверяется так:
Код

if( Foto.IsEmpty())...;

Автор: Albor 19.5.2010, 10:09
Цитата(eugeniy @  18.5.2010,  23:41 Найти цитируемый пост)
Потом же после выборки я попадаю сюда:

В этом месте установи Foto из CReaderDlg

Автор: eugeniy 19.5.2010, 22:16
Цитата(Albor @ 19.5.2010,  10:09)
Цитата(eugeniy @  18.5.2010,  23:41 Найти цитируемый пост)
Потом же после выборки я попадаю сюда:

В этом месте установи Foto из CReaderDlg

Когда я объявляю в одном классе CReaderDlg переменную foto, то при компиляции он мне пишет:
c:\program files\microsoft visual studio\vc98\bin\reader(3)\reader\reader_writer.cpp(258) : error C2065: 'Foto' : undeclared identifier

подключил хэдер readerDlg.h, переменная объявлена как public, не понимаю почему reader_writer.cpp не может до неё достучаться!?

Да, кстати, когда я делал с другими переменными
Код

CString Imya;
CString Familiya;
CString Kurs;
CString Fakultet;
CString Ot4estvo;


я же их объявлял и в CReaderDlg и в CReader и всё работало отлично. А тут что-то капризничает. 

Автор: Albor 20.5.2010, 06:58
Цитата(eugeniy @  19.5.2010,  22:16 Найти цитируемый пост)
я же их объявлял и в CReaderDlg и в CReader и всё работало отлично. А тут что-то капризничает.

вот фрагмент твоего кода:
Код

m_fakultet_CTRL.SetWindowText(m_reader->Fakultet);

Здесь ты копируешь текст из CReader в контрол принадлежащий CReaderDlg. Почему у тебя возникает проблема копирования строки - не понимаю. Делай по шагам:
1. Объяви в CReaderDlg переменную CString m_ImageFileName;
2. В OnTimer, где читаешь карточку и перебрасываешь данные в CReaderDlg, присваиваешь этой переменной значение
Код

m_ImageFileName=m_reader->Foto;

Цитата(eugeniy @  19.5.2010,  22:16 Найти цитируемый пост)
Когда я объявляю в одном классе CReaderDlg переменную foto, то при компиляции он мне пишет:
c:\program files\microsoft visual studio\vc98\bin\reader(3)\reader\reader_writer.cpp(258) : error C2065: 'Foto' : undeclared identifier

Правильно, ты объявил переменную в одном классе, а пытаешься доступиться к ней из другого, а этот "другой" ни слухом ни духом не знает о первом. После того, как объявляешь с тем же именем переменную в "слепом" классе, компилятор перестаёт ругаться, но данные то остаются в CReader::Foto, а CReaderDlg::Foto, как была пустой при создании, так и осталась. Кстати, разницу в именах переменных заметил? smile

Автор: eugeniy 29.5.2010, 15:44
Цитата
 Делай по шагам:
1. Объяви в CReaderDlg переменную CString m_ImageFileName;
2. В OnTimer, где читаешь карточку и перебрасываешь данные в CReaderDlg, присваиваешь этой переменной значение
Код

m_ImageFileName=m_reader->Foto;


всё сделал так как вы сказали, получилось вот так:
Код

class CReaderDlg : public CDialog
{
// Construction
public:
CString m_foto;


Код
class CReader
{
    public:
    CString Foto;


Код
void CReaderDlg::OnTimer(UINT nIDEvent) 
{
    CDialog::OnTimer(nIDEvent);

    m_reader = new CReader;
    if(!(m_reader->Reader_Init()))
        EndDialog(0);
    
        if(!(m_reader->Read_serial_number()))
            EndDialog(0);

            
        if(m_reader->Card_read())
        {
            m_foto = m_reader->Foto;

после этого фото всё равно не выводит на главном диалоге, а когда нажимаю кнопку "заявление на мат.помощь" выводится второй диалог и после его закрытия, на главном диалоге прорисовывается фото и вылетает с ошибкой
следующего содержания:
Debug Assertion Failed!

Program:...
File: c:\program files\microsoft visual studio 8\vc\atlmfc\include\atlimage.h
Line:503

Expression: m_hBitmap==0

вот так(

Код
BOOL CReaderDlg::OnEraseBkgnd(CDC* pDC) 
{    
    CRect rect;
    GetClientRect(&rect);
    CBrush brush;
    DWORD color = GetSysColor(COLOR_3DFACE);
    brush.CreateSolidBrush(color);
    pDC->FillRect(&rect,&brush);
            
    if (m_foto.IsEmpty())
        return false;

    image.Load(LPCTSTR(m_foto));


Цитата
 Кстати, разницу в именах переменных заметил? smile


если честно нет)

Автор: Albor 30.5.2010, 13:12
Цитата(eugeniy @  29.5.2010,  15:44 Найти цитируемый пост)
если честно нет) 

CReader::Foto и CReaderDlg::Foto - это полные имена переменных, состоящих из области видимости и имени переменной. Имена самих переменных одинаковые, а область видимости разная. Это всё равно, что записать файл с именем foto.bmp на диск С и на диск D, если изменить файл на диске С, то на D, он останется неизменённым и наоборот.
По рисованию: судя по ошибке - попытка нарисовать "пустую" картинку. Перед вызовом функции рисования картинки, проверяй m_hBitmap и рисуй, если он не равен нулю.

Автор: eugeniy 7.6.2010, 01:38
Всё вроде работает. Отлично выводит картинку. 
вот кусок рабочего кода, отвечающий за вывод картинки.
Код

CImage image, image2;
image.Load(LPCTSTR(m_reader->Foto));
    
int w = image.GetWidth(); 
int h = image.GetHeight();    
int tnh = 200;
int tnw = 200 * w / h;
int bpp = image.GetBPP();

image2.Create(tnw,tnh,bpp);
HDC h2 = image2.GetDC();
SetStretchBltMode(h2, HALFTONE);
image.StretchBlt(h2,0,0,tnw,tnh,SRCCOPY);    
image2.ReleaseDC();
m_photo.SetBitmap(image2);    


можно узнать как проверить существование файла? есть ли в mfc какие-нить средства?    

Автор: Albor 7.6.2010, 07:48
Цитата(eugeniy @  7.6.2010,  01:38 Найти цитируемый пост)
можно узнать как проверить существование файла? есть ли в mfc какие-нить средства?   

Есть класс CFile. Его метод Open, возвращает логическое значение.

Добавлено через 3 минуты и 44 секунды
Или посмотри в сторону класса CFileFind

Автор: eugeniy 10.6.2010, 01:31
А можете показать как правильно сделать проверку на существование файла?

Спасибо

Автор: Albor 10.6.2010, 09:45
Можно так:
Код

#include <shlwapi.h>
//.......
if(PathFileExists(_T("1.txt"))) 
   MessageBox(_T("File Exist"));
else 
   MessageBox(_T("File NOT Exist"));

Автор: eugeniy 10.6.2010, 13:03
Цитата(Albor @ 10.6.2010,  09:45)
Можно так:
Код

#include <shlwapi.h>
//.......
if(PathFileExists(_T("1.txt"))) 
   MessageBox(_T("File Exist"));
else 
   MessageBox(_T("File NOT Exist"));

спасибо

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)