Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> IDropTarget и файлы, IDropTarget 
V
    Опции темы
Emura
Дата 20.1.2011, 02:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 102
Регистрация: 7.2.2009

Репутация: 1
Всего: 1



всем привет!

подскажите пожалуйста со следующим глючком.


- кидаем папку из эксплорера в окно (IDropTarget).
- обрабатываем файлы из папки(специфика программы).
окно эксплорера (откуда бралась папка) подвисает на время обработки.  


IDropTarget::Drop такого вида.

IDropTarget::Drop(...)
{
извлекаем путь папки
PostMessage( путь папки, ...);
}

из функции IDropTarget::Drop() успешно выходим перед тем как приходит сообщение от PostMessage, т.е. блокировать обработка не должна.. но.. smile как избежать этого зависания?


многопоточности нет, XP. 
всё дело встало, подскажите кто догадается, спасибо smile 


тестовый проект
Код

#include <windows.h>


static const wchar_t* const gWindowClassName =L"-TEST_CLASS_NAME-";
static const UINT WM_MAGIC =WM_APP + 0x4400;


    static LRESULT CALLBACK gWindowProc( HWND h, const UINT message, const WPARAM wParam, const LPARAM lParam )
    {

        switch ( message )
        {
        case WM_DESTROY:
            {
                ::PostQuitMessage(0);
                return 0;
                break;
            }
        case WM_MAGIC:
            {
                for ( int i=0; i<50; ++i )
                {
                    ::Sleep(100);
                }
                return 0;
                break;
            }
        }

        return ::DefWindowProcW( h, message, wParam, lParam );

    };


    class MyDropTarget : public IDropTarget
    {
    private:
        ULONG        m_refCount;
        HWND        m_owner;
        wchar_t        m_data[1024];
    public:
        MyDropTarget( HWND owner ):
          m_refCount    ( 1 ),
              m_owner        ( owner )
          {
          }
          virtual ~MyDropTarget()
          {
          }
          HRESULT __stdcall QueryInterface( REFIID id, void FAR* FAR* result )
          {
              if ( id==IID_IUnknown || 
                  id==IID_IDropTarget )
              {
                  *result =this;
                  AddRef();
                  return NOERROR;
              }
              *result =NULL;
              return ResultFromScode(E_NOINTERFACE);
          }
          ULONG __stdcall AddRef()    
          { 

              return ++m_refCount;
          }
          ULONG __stdcall Release()   
          { 
              if ( --m_refCount==0 ) 
              {
                  delete this; 
                  return 0;
              }
              return m_refCount; 
          }
          HRESULT __stdcall DragEnter( IDataObject* dataObject, DWORD grfKeyState, POINTL mousePos, DWORD* effect )
          {
              *effect =DROPEFFECT_COPY;
              return NOERROR;
          }
          HRESULT __stdcall DragOver( DWORD keyState, POINTL mousePos, DWORD* effect )
          {
              *effect =DROPEFFECT_COPY;
              return NOERROR;
          }
          HRESULT __stdcall DragLeave()
          {
              return NOERROR;
          }
          HRESULT __stdcall Drop( IDataObject* dataObject, DWORD keyState, POINTL mousePos, DWORD* effect )
          {
              BOOL r =::PostMessageW( m_owner, WM_MAGIC, 0, (LPARAM)0 );
              *effect =DROPEFFECT_COPY;
              return NOERROR;
          }
    };



    INT WINAPI WinMain( HINSTANCE, HINSTANCE, char*, INT )
    {

        ::OleInitialize(NULL);

        WNDCLASSEX wc;
        ::memset( &wc, 0, sizeof(wc) );
        wc.cbSize =sizeof(wc);
        wc.lpfnWndProc =(WNDPROC)gWindowProc;
        wc.cbWndExtra =4;
        wc.hInstance =::GetModuleHandleW(0);
        wc.lpszClassName =gWindowClassName;
        wc.hbrBackground =(HBRUSH)::GetStockObject( WHITE_BRUSH );
        wc.hCursor =::LoadCursorW( NULL, IDC_ARROW );
        ::RegisterClassExW( &wc );


        HWND h =::CreateWindowExW(
            0, 
            wc.lpszClassName,
            NULL,
            WS_OVERLAPPEDWINDOW, 
            100, 100,
            200, 200, 
            NULL, 
            NULL,
            ::GetModuleHandleW(0), 
            NULL );

        ::ShowWindow( h, SW_NORMAL );


        MyDropTarget dt(h);
        HRESULT result =::RegisterDragDrop( h, &dt );


        MSG m;
        while ( ::GetMessageW( &m, NULL, 0, 0 )>0 )
        {
            ::TranslateMessage( &m );
            ::DispatchMessageW( &m );
        }


        ::RevokeDragDrop( h );
        ::DestroyWindow( h );
        ::UnregisterClassW( gWindowClassName, ::GetModuleHandleW(0) );
        ::OleUninitialize();


        return 0;

    };






Это сообщение отредактировал(а) Emura - 20.1.2011, 04:24
PM   Вверх
GremlinProg
Дата 20.1.2011, 10:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



поток-то все равно один, поэтому если эксплорер ждет какой-то синхронной с очередью сообщений реакции после Drop,
то он и будет висеть, пока WM_MAGIC не вернется

можно попробовать 2 варианта:

1. поставить в Drop таймер на несколько мс (чтобы отвязаться от эксплорера), на который, после срабатывания повесить обработку или посылку WM_MAGIC
2. пустить новый или возобновляющийся поток, исполняющий работу WM_MAGIC


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Emura
Дата 20.1.2011, 12:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 102
Регистрация: 7.2.2009

Репутация: 1
Всего: 1



GremlinProg,
да уж, думалось что PostMessage спасет, а получается что нет..

по поводу таймера, самому пришла такая идея в голову, да только как-то и так везде использую таймеры.. таймеры, которые уже ассоциируются с костылями... smile

на счет дополнительного потока хз.. для такой "мелочи".. smile 

попробую очередной ннннн-ый таймер smile 

интересную особенность заметил, если во время блока обработки( в тесте блок WM_MAGIC) выскакивает мессаджбокс(вызываемый алгоритмом обработки), то explorer размораживается.. магия виндовс блин smile 

Это сообщение отредактировал(а) Emura - 20.1.2011, 12:11
PM   Вверх
GremlinProg
Дата 20.1.2011, 21:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(Emura @  20.1.2011,  14:10 Найти цитируемый пост)
интересную особенность заметил, если во время блока обработки( в тесте блок WM_MAGIC) выскакивает мессаджбокс(вызываемый алгоритмом обработки), то explorer размораживается.. магия виндовс блин  

это нормально,
просто мессаджбокс имеет свой цикл обработки сообщений, поэтому любой вызов MessageBox или DialogBox в такой момент будет продолжать работу первичного цикла сообщений потока (того самого, который висит)


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Emura
Дата 20.1.2011, 22:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 102
Регистрация: 7.2.2009

Репутация: 1
Всего: 1



GremlinProg, очередной респект! таймер помог. smile 
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0481 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.