Привет!
Создал отдельный поток и в нем в определенный момент пытаюсь изменить всего-навсего титл документа CDocument::SetTitle, на что во время работы вскакивает ошибка о нарушение доступа.
Хотя в нутри потока где класс CView все работает нормально.
Подскажите как обойти эту проблему?
Спасибо.
Posted via RSDN NNTP Server 1.7 "Bedlam"
M>Привет!
M>Создал отдельный поток и в нем в определенный момент пытаюсь изменить всего-навсего титл документа CDocument::SetTitle, на что во время работы вскакивает ошибка о нарушение доступа.
M>Хотя в нутри потока где класс CView все работает нормально.
M>Подскажите как обойти эту проблему?
M>Спасибо.
Всё правильно, Вы обращяетесь из другого потока к классу Документ по указателю на него, так? Указатели при переходе через границу потока протухают и их нельзя более использовать.
Могу предложить Вам такое решение:
1.Заведите глобальную переменную hWnd с типом HWND, которая будет видна из любого потока и будет хранить описатель окна.
2. В другом потоке вместо обращения к Документу напишите строчку:
char * title = "Hello world";
PostMessage(hWnd, WM_SETTEXT, 0, (LPARAM)title);
Вот и всё.
Странно, я потоку передаю указатель на 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"
Я посмотрел, как сделана функция 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);
Удачи!
Спасибо!
+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"