Не работает SetWindowLong GWL_USERDATA :(

Тема в разделе "WASM.BEGINNERS", создана пользователем da-007, 24 фев 2008.

  1. da-007

    da-007 New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2006
    Сообщения:
    13
    Добрый день.

    Создаю кучу дочерних окошек:

    ...
    // Габариты и координаты - реальные
    hWnd = CreateWindowEx (0, "STATIC", NULL, WS_CHILD | WS_VISIBLE | SS_BITMAP, 0, 0, 20, 20, hWndParent, NULL, hInst, 0);
    ...
    // Сабклассинг
    SetWindowLong (hWnd, GWL_WNDPROC, WndProc);
    ...

    Теперь обработчик сообщений дочерних окошек:
    ...
    // hWnd - это параметр ф-ии WndProc
    // Не работает, всегда возвращает ноль, GetLastError() возвращает 1413 - INVALID_INDEX
    SetWindowLong (hWnd, GWL_USERDATA, 1);
    ...

    Что я делаю неправильно?
     
  2. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    собственно читаем msdn. там черным по белому: hWnd - диалог.
     
  3. diamond

    diamond New Member

    Публикаций:
    0
    Регистрация:
    21 май 2004
    Сообщения:
    507
    Адрес:
    Russia
    n0name
    Это про фразу
    что ли? Так она относится к "the following values", то есть DWL_*, но не к GWL_USERDATA.
    da-007
    Там же (описание SetWindowLong) другая полезная фраза есть:
    Класс окна "STATIC" регистрирует система, и при регистрации там, видимо, не резервируется дополнительная память под GWL_USERDATA (действительно, зачем static'у user data?) Так что записать туда что-нибудь не удастся.
     
  4. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
    По MSDN - GWL_USERDATA это 4 байта на любые нужды. По логике должно работать даже с COMBOBOX.
     
  5. diamond

    diamond New Member

    Публикаций:
    0
    Регистрация:
    21 май 2004
    Сообщения:
    507
    Адрес:
    Russia
    Действительно. Но вот ещё одна цитата (http://blogs.msdn.com/oldnewthing/archive/2005/03/03/384285.aspx):
    Этими значениями должен распоряжаться код "внутренностей" класса (aka оригинальная оконная процедура) (условно говоря, тот же COMBOBOX имеет полное право хранить там указатель на какие-то свои внутренние данные, и если кто-то посторонний нагло перезаписывает этот указатель, поведение оконной процедуры COMBOBOX'а непредсказуемо). Ну а в случае с системным классом STATIC, которому это поле не нужно, возможно, для экономии памяти просто не выделяется полная версия структуры.
     
  6. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    da-007
    Может дело в этом и SetWindowLong на самом деле успешно отрабатывает?
     
  7. tinok

    tinok New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2007
    Сообщения:
    26
    А ты пробовал проверять после значение с помощью GetWindowLong(hWnd, GWL_USERDATA) ? Если ты не теряешь хендл hWnd на полпути, то все обязано работать.

    P.S. Для диалогов помимо GWL_USERDATA ещё существует DWL_USER (для любых окон - GWL_USERDATA присутствует всегда).
     
  8. kero

    kero Модератор SOURCES & 2LZ Команда форума

    Публикаций:
    0
    Регистрация:
    4 апр 2006
    Сообщения:
    1.074
    Адрес:
    Москва
    diamond
    ??
    Что помешало проверить на живом статике до того, как озвучить эти нелепые фантазии ?

    Вот он, статик без мистики:
    Код (Text):
    1. .data
    2.  _static db "static",0
    3. .data?
    4. .code
    5.  
    6. SubProc proc hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
    7.   .if uMsg==WM_PAINT
    8.     invoke GetWindowLong,hWnd,GWL_USERDATA
    9.     invoke CallWindowProc,eax,hWnd,uMsg,wParam,lParam
    10.   .else
    11.     invoke DefWindowProc,hWnd,uMsg,wParam,lParam
    12.   .endif
    13.   ret
    14. SubProc endp
    15.  
    16. SubClass proc hWnd:HWND,lpp:DWORD
    17.   invoke SetWindowLong,hWnd,GWL_WNDPROC,lpp
    18.   invoke SetWindowLong,hWnd,GWL_USERDATA,eax
    19.   invoke GetClassLong,hWnd,GCL_STYLE
    20.   and eax,not CS_PARENTDC
    21.   push eax
    22.   invoke SetClassLong,hWnd,GCL_STYLE,eax
    23.   invoke SetWindowLong,hWnd,GWL_EXSTYLE,WS_EX_LAYERED OR WS_EX_CLIENTEDGE
    24.   invoke SetWindowPos,hWnd,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE OR SWP_NOSIZE OR SWP_FRAMECHANGED
    25.   invoke SetLayeredWindowAttributes,hWnd,0,180,LWA_ALPHA
    26.   pop eax
    27.   or eax,CS_PARENTDC
    28.   invoke SetClassLong,hWnd,GCL_STYLE,eax
    29.   mov eax,hWnd
    30.   ret
    31. SubClass endp
    32.  
    33. start:
    34.   invoke GetModuleHandle,0
    35.   invoke CreateWindowEx,0,offset _static,offset _static,WS_OVERLAPPEDWINDOW OR WS_VISIBLE,20,20,300,200,0,0,eax,0
    36.   invoke SubClass,eax,addr SubProc
    37.   invoke MessageBox,0,offset _static,0,MB_TOPMOST
    38.   invoke ExitProcess,eax
    39. end start