Re[3]: Обращение к CDoucument из другого потока.
От: Trapper  
Дата: 17.01.04 11:37
Оценка: 3 (1)
Я посмотрел, как сделана функция SetTitle в Документе. Она присваивает новое значение для заголовка, а потом проходит по всем видам, которые закреплены за этим документом и вызывает для каждого метод OnUpdate. При этом используется карта окошек (если хочешь подробностей, посмотрите исходники MFC). Проблема в том, что при переходе через границу потока эта карта "ломается" и вызывается ASSERT. Тут, к сожалению, ничего нельзя сделать. В исходниках MFC специально написано, что в этом случае единственный способ — это использование объектов вроде HWND, которые ведут себя одинакого в любом потоке.
Поэтому я Вам и предложил вариант с сообщениями, который использует HWND. Если Вам потребуется сделать что — то, для чего нет соотв. сообщения в Windows (к примеру, вызвать какую — нибудь функцию из Документа), то есть такой вариант:
1. Объявляете с помощью #define новое сообщение:
#define WM_NEWMESSAGE 10000


Потом в файле MainFrame.cpp вставляешь код:
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
...
    ON_MESSAGE(WM_NEWMESSAGE, OnNewMessage)
...
END_MESSAGE_MAP()
...
LRESULT CMainFrame::OnNewMessage(WPARAM wParam, LPARAM lParam)
{
    //Эта функция будет вызвана уже из контекста приложения, 
      //поэтому можешь обращаться отсюда к Документу и к любым другим объектам
}


И ещё одну строчку в файле MainFrame.h:
class CMainFrame : public CFrameWnd
{
...
    afx_msg LRESULT OnNewMessage(WPARAM wParam, LPARAM lParam);
};


Потом из другого потока отправляешь сообщение:
SendMessage(hWnd, WM_NEWMESSAGE, par1, par2);


Удачи!
Trapper
Обращение к CDoucument из другого потока.
От: machine1 Россия  
Дата: 17.01.04 08:48
Оценка:
Привет!

Создал отдельный поток и в нем в определенный момент пытаюсь изменить всего-навсего титл документа CDocument::SetTitle, на что во время работы вскакивает ошибка о нарушение доступа.
Хотя в нутри потока где класс CView все работает нормально.
Подскажите как обойти эту проблему?
Спасибо.
Posted via RSDN NNTP Server 1.7 "Bedlam"
:: machine1
Re: Обращение к CDoucument из другого потока.
От: Trapper  
Дата: 17.01.04 09:36
Оценка:
M>Привет!

M>Создал отдельный поток и в нем в определенный момент пытаюсь изменить всего-навсего титл документа CDocument::SetTitle, на что во время работы вскакивает ошибка о нарушение доступа.

M>Хотя в нутри потока где класс CView все работает нормально.
M>Подскажите как обойти эту проблему?
M>Спасибо.

Всё правильно, Вы обращяетесь из другого потока к классу Документ по указателю на него, так? Указатели при переходе через границу потока протухают и их нельзя более использовать.
Могу предложить Вам такое решение:
1.Заведите глобальную переменную hWnd с типом HWND, которая будет видна из любого потока и будет хранить описатель окна.
2. В другом потоке вместо обращения к Документу напишите строчку:

char * title = "Hello world";
PostMessage(hWnd, WM_SETTEXT, 0, (LPARAM)title);

Вот и всё.
Trapper
Re[2]: Обращение к CDoucument из другого потока.
От: Trapper  
Дата: 17.01.04 09:38
Оценка:
Хотя тут лучше не PostMessage, а SendMessage.
Trapper
Re[2]: Обращение к CDoucument из другого потока.
От: machine1 Россия  
Дата: 17.01.04 10:02
Оценка:
Странно, я потоку передаю указатель на CView. Когда я вызываю ф-ии-члены класса-все работает.
И вот когда вызываю CView::GetDocument() происходит ошибка.
Сообщения работают но так делать не хочется — это на крайний случай
DWORD WINAPI SomeThread(PVOID pParam)

{

CListView* pView = (СListView*)pParam;

// Работает

pView->MyFunc();

// Тут происходит ошиба

pView->GetDocument()->SetTitle("bla-bla-bla");



//........

}




"Trapper" <forum@rsdn.ru> wrote in message news:509597@news.rsdn.ru...
>
> M>Привет!
>
> M>Создал отдельный поток и в нем в определенный момент пытаюсь изменить всего-навсего титл документа CDocument::SetTitle, на что во время работы вскакивает ошибка о нарушение доступа.
> M>Хотя в нутри потока где класс CView все работает нормально.
> M>Подскажите как обойти эту проблему?
> M>Спасибо.
>
> Всё правильно, Вы обращяетесь из другого потока к классу Документ по указателю на него, так? Указатели при переходе через границу потока протухают и их нельзя более использовать.
> Могу предложить Вам такое решение:
> 1.Заведите глобальную переменную hWnd с типом HWND, которая будет видна из любого потока и будет хранить описатель окна.
> 2. В другом потоке вместо обращения к Документу напишите строчку:
>
>
> char * title = "Hello world";
> PostMessage(hWnd, WM_SETTEXT, 0, (LPARAM)title);
>

> Вот и всё.
Posted via RSDN NNTP Server 1.7 "Bedlam"
:: machine1
Re[4]: Обращение к CDoucument из другого потока.
От: machine1 Россия  
Дата: 17.01.04 12:02
Оценка:
Спасибо!
+3

"Trapper" <forum@rsdn.ru> wrote in message news:509675@news.rsdn.ru...
> Я посмотрел, как сделана функция SetTitle в Документе. Она присваивает новое значение для заголовка, а потом проходит по всем видам, которые закреплены за этим документом и вызывает для каждого метод OnUpdate. При этом используется карта окошек (если хочешь подробностей, посмотрите исходники MFC). Проблема в том, что при переходе через границу потока эта карта "ломается" и вызывается ASSERT. Тут, к сожалению, ничего нельзя сделать. В исходниках MFC специально написано, что в этом случае единственный способ — это использование объектов вроде HWND, которые ведут себя одинакого в любом потоке.
> Поэтому я Вам и предложил вариант с сообщениями, который использует HWND. Если Вам потребуется сделать что — то, для чего нет соотв. сообщения в Windows (к примеру, вызвать какую — нибудь функцию из Документа), то есть такой вариант:
> 1. Объявляете с помощью #define новое сообщение:
>
> #define WM_NEWMESSAGE 10000
>

>
> Потом в файле MainFrame.cpp вставляешь код:
>
> BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
> ...
> ON_MESSAGE(WM_NEWMESSAGE, OnNewMessage)
> ...
> END_MESSAGE_MAP()
> ...
> LRESULT CMainFrame::OnNewMessage(WPARAM wParam, LPARAM lParam)
> {
> //Эта функция будет вызвана уже из контекста приложения, 
>       //поэтому можешь обращаться отсюда к Документу и к любым другим объектам
> }
>

>
> И ещё одну строчку в файле MainFrame.h:
>
> class CMainFrame : public CFrameWnd
> {
> ...
>     afx_msg LRESULT OnNewMessage(WPARAM wParam, LPARAM lParam);
> };
>

>
> Потом из другого потока отправляешь сообщение:
>
> SendMessage(hWnd, WM_NEWMESSAGE, par1, par2);
>

>
> Удачи!
Posted via RSDN NNTP Server 1.7 "Bedlam"
:: machine1
Re[5]: Обращение к CDoucument из другого потока.
От: Trapper  
Дата: 17.01.04 13:18
Оценка:
Не за что
Trapper
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.