Форум программистов, компьютерный форум, киберфорум
Visual C++
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.79/19: Рейтинг темы: голосов - 19, средняя оценка - 4.79
1 / 1 / 0
Регистрация: 09.12.2008
Сообщений: 87
1

Как сделать SafeArray (MFC)?

22.12.2008, 16:58. Показов 3764. Ответов 15
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Сабж, как используя MFC создать SafeArray и сделать метод который принимая их контейнера массив вариантов и пихал его в SafeArray (размеры массива харанее неизвестны).

Интересует конкретный момент приема данных из контейнера(в методе) и инициализации SafeArray.

Блин, совсем запутался что там и как :-(((
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
22.12.2008, 16:58
Ответы с готовыми решениями:

[MFC] Как сделать картинку кнопкой
Название говорит само за себя. Находил на сайте подобные темы: Тык1, тык2. Написано не совсем...

Как сделать рабочий ехе в MFC
Пишу проект MFC, ехе не запускается на других машинах без отладки в VS. Как сделать, чтобы его...

Как сделать MFC статической, а не динамической?
это всё тоже из серии "Не работает exe файл на других компах" я предлагаю засунуть в эту тему все...

MFC как сделать, или нажать кнопку
вообщем есть 4 текст бокса и кнопка. Приложение в режиме диалога. Если кликнуть в текстбокс и...

15
7 / 7 / 12
Регистрация: 13.02.2007
Сообщений: 1,255
22.12.2008, 19:27 2
Посмотри пример от Microsoft, может поможет:

http://support.microsoft.com/default.aspx?scid=kb;en-us;Q140202

Удачи, Владимир
0
1 / 1 / 0
Регистрация: 09.12.2008
Сообщений: 87
23.12.2008, 11:29  [ТС] 3
Нет, я явно делаю что-то не так :-(

Вот метод в моем ActiveX контроле:
C++
1
2
3
4
5
6
7
8
9
void CTableCtrl::getData(const VARIANT FAR& myData) 
{
    lNumRows = 0;
    lNumCols = 0;
    LPSAFEARRAY lpSA = V_ARRAY(&myData);
    myDataArray = new COleSafeArray(lpSA, VT_BSTR);
    myDataArray -> GetUBound(1, &lNumRows);
    myDataArray -> GetUBound(2, &lNumCols);
}
Вот я из VB передаю туда массив:
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
Private Sub TableControl_Enter()
    Dim textData(1 To 10, 1 To 16) As Variant
    Dim i As Integer
    Dim j As Integer
    
    For i = 1 To 10
        For j = 1 To 10
            textData(i, j) = 'text'
        Next
    Next
    TableControl.getData (textData)  '<--- вот тут
End Sub
Так вот у меня программа 'выолняет недопустимую операцию' и падает замертво :-(
При чем происходит это при попытке узнать кол-во элементов массива, то есть если в методе закомментарить строчки вида:
C++
1
    myDataArray -> GetUBound(1, &lNumRows);
То ни чего не падает.... но и работать с массивом соответственно никак :-(
0
7 / 7 / 12
Регистрация: 13.02.2007
Сообщений: 1,255
23.12.2008, 11:50 4
Выдержка из примера от Microsoft:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
long CMfcarrayDoc::FastSort(const VARIANT FAR& vArray) 
{
    long i, j, min;
    BSTR bstrTemp;
    SAFEARRAY FAR* FAR* ppsa = NULL;
    BSTR HUGEP *pbstr;
    HRESULT hr;
    DWORD dwTimeStart; 
    LONG cElements, lLBound, lUBound;
    
    USES_CONVERSION;
 
    // Type check VARIANT parameter. It should contain a BSTR array passed by reference.
    // The array must be passed by reference it is an in-out-parameter.
    if (V_VT(&vArray) != (VT_BYREF | VT_ARRAY | VT_BSTR))
        AfxThrowOleDispatchException(1001, 'Type Mismatch in Parameter. Pass a string array by reference');
    ppsa = V_ARRAYREF(&vArray);
    // Check dimensions of array                
    if (SafeArrayGetDim(*ppsa) != 1)                 
        AfxThrowOleDispatchException(1002, 'Type Mismatch in Parameter. Pass a one-dimensional array');
        
    dwTimeStart = GetTickCount();
    
    // Get array bounds
    hr = SafeArrayGetLBound(*ppsa, 1, &lLBound);
    if (FAILED(hr))
        goto error;            
    hr = SafeArrayGetUBound(*ppsa, 1, &lUBound);
    if (FAILED(hr))
        goto error; 
    
    // Get a pointer to the the elements of the array     
    hr = SafeArrayAccessData(*ppsa, (void HUGEP* FAR*)&pbstr);
    if (FAILED(hr))
       goto error;       
    
    // Bubble sort
    cElements = lUBound-lLBound+1;   
    for (i = 0; i < cElements-1; i++)
    {
        min = i;
        for (j = i+1; j < cElements; j++)
        {   
            // NULL is a valid value for a BSTR. This code treats a NULL BSTR
            // as less than other string values.
            if (pbstr[min] == NULL)
                continue;   
            else if (pbstr[j] == NULL 
                || lstrcmp(OLE2T(pbstr[j]), OLE2T(pbstr[min])) < 0)
                min = j; 
 
        }
         
        //Swap array[min] and array[i]
        bstrTemp = pbstr[min];
        pbstr[min] = pbstr[i];
        pbstr[i] = bstrTemp;        
    }
    
    hr = SafeArrayUnaccessData(*ppsa);
    if (FAILED(hr))
       goto error;
    
    return GetTickCount()-dwTimeStart;
    
error:
   AfxThrowOleDispatchException(1003, 'Unexpected Failure in FastSort method');
   return 0;
}
У тебя чявно это реализовано по другому...
Проверь еще раз!

С уважением, Владимир
0
1 / 1 / 0
Регистрация: 09.12.2008
Сообщений: 87
23.12.2008, 12:02  [ТС] 5
'USES_CONVERSION' : undeclared identifier

Я пишу ActiveX control и проект у меня не просто MFC-шный а 'MFC ActiveX control wizard'.
Да, Visual Studio 6 (пока без сервиспаков :-( ).
0
7 / 7 / 12
Регистрация: 13.02.2007
Сообщений: 1,255
23.12.2008, 12:07 6
Забудь про USES_CONVERSION
Смотри как они преобразуют vArray (в твоем случае myData):
C++
1
SAFEARRAY FAR* FAR* ppsa = V_ARRAYREF(&vArray);
и затем
C++
1
HRESULT hr = SafeArrayGetLBound(*ppsa, 1, &lLBound);
...
0
7 / 7 / 12
Регистрация: 13.02.2007
Сообщений: 1,255
23.12.2008, 12:11 7
Без сервис паков - это плохо, нужно хотя бы SP3 для нормальной работы с ActiveX в VB.
0
1 / 1 / 0
Регистрация: 09.12.2008
Сообщений: 87
23.12.2008, 12:17  [ТС] 8
Спасибо, заработало !

P.S. Ну вы это, не расслабляйтесь, у меня еще много вопросов будет :-)))
0
7 / 7 / 12
Регистрация: 13.02.2007
Сообщений: 1,255
23.12.2008, 12:28 9
0
1 / 1 / 0
Регистрация: 09.12.2008
Сообщений: 87
24.12.2008, 09:39  [ТС] 10
Привет, продолжим? :-)

Передал я массив вариантов как написано в примере выше, массив двумерный размеры определяются, всё Ок, но вот что-то мне не вытащить элементы массива, как мне конвертнуть это в текст?
Внагляк сделать так:
char buffer[20];
buffer = pbstr[i][j];
есс-но не пашет...

Во-от....
0
7 / 7 / 12
Регистрация: 13.02.2007
Сообщений: 1,255
24.12.2008, 11:44 11
Продолжим следовать строкам примера (ссылку на который я бросил в самом начале и кусок кода приведен выше) ...
Для начала получи указатель на данные из SafeArray:
C++
1
2
BSTR HUGEP *pbstr;
SafeArrayAccessData(*ppsa, (void HUGEP* FAR*)&pbstr);
далее попробуй выдернуть строку, не уверен, но навверно это должно выглядеть так:
C++
1
BSTR bstrTemp = OLE2T(pbstr[i][j]);
Счастья вам, Владимир
0
1 / 1 / 0
Регистрация: 09.12.2008
Сообщений: 87
24.12.2008, 11:50  [ТС] 12
-> BSTR bstrTemp = OLE2T(pbstr[i][j]);

error C2065: '_lpw' : undeclared identifier
error C2065: '_convert' : undeclared identifier

:-(
0
1 / 1 / 0
Регистрация: 09.12.2008
Сообщений: 87
24.12.2008, 12:50  [ТС] 13
И кстати, если у меня двумерный массив то обращаться к элементу так:
pbstr[i*sizeofRow+j]

???
0
7 / 7 / 12
Регистрация: 13.02.2007
Сообщений: 1,255
24.12.2008, 13:01 14
Идем в MSDN, набираем в строке поиска 'OLE2T macros'.

Первая ссылка - String Conversion Macros:
http://msdn.microsoft.com/library/en-us/vcmfc98/html/_atl_string_conversion_macros.asp

Там читаем
Note: When using an ATL string conversion macro, specify the USES_CONVERSION macro at the beginning of your function in order to avoid compiler errors.

По ссылке на TN059: Using MFC MBCS/Unicode Conversion Macros:
http://msdn.microsoft.com/library/en-us/vcmfc98/html/_mfcnotes_tn059.asp
находим - All of the macros reside in AFXPRIV.H

То есть все что надо сделать это начале файла включить:

#include 'afxpriv.h'

и в начале функции вызвать:

USES_CONVERSION;

Дерзайте, Владимир
0
7 / 7 / 12
Регистрация: 13.02.2007
Сообщений: 1,255
24.12.2008, 13:28 15
Кстати, в MSDN есть хорошие примерчики к описаниям функций:

http://msdn.microsoft.com/library/en-us/automat/htm/chap7_5bs1.asp
http://msdn.microsoft.com/library/en-us/automat/htm/chap7_5p84.asp

и вообще

http://msdn.microsoft.com/library/en-us/automat/htm/chap7_5dyr.asp

Впрочем, есть такой замечательный класс COleSafeArray:

http://msdn.microsoft.com/library/en-us/vclib/html/_mfc_COleSafeArray.asp
http://msdn.microsoft.com/library/en-us/vclib/html/_mfc_colesafearray_class_members.asp

Который все это дело заворачивает и упрощает см.

http://msdn.microsoft.com/library/en-us/vclib/html/_mfc_colesafearray.3a3a.accessdata.asp

С уважением, Владимир
0
1 / 1 / 0
Регистрация: 09.12.2008
Сообщений: 87
24.12.2008, 14:10  [ТС] 16
Спасибо ! :-)
0
24.12.2008, 14:10
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
24.12.2008, 14:10
Помогаю со студенческими работами здесь

Как сделать просмотр HTML в MFC Диалоге?
Как сделать просмотр HTML страницы в MFC Диалоге(ресурсы .rc)?

Как сделать посредством MFC бегущую строку?
Как сделать при помощи MFC (Visual C++ 2012) бегущую строку? То есть есть текст, сперва он...

Как сделать чтобы кнопка в диалоговом окне не подсвечивалась до того, как на нее наведешь мышкой? (MFC)
Как сделать чтобы кнопка в диалоговом окне не подсвечивалась mfc до того, как на нее наведешь...

MFC Приложение: как сделать одновременное использование кнопок
Здравствуйте, у меня следующая задача: В цикле (100 итераций) через определенные промежутки времени...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru