Языковая панель

Тема в разделе "WASM.BEGINNERS", создана пользователем gale1238, 1 июн 2010.

  1. gale1238

    gale1238 New Member

    Публикаций:
    0
    Регистрация:
    21 мар 2009
    Сообщения:
    72
    Не получается спрятать/показать Language bar.
    Наверное нужно использовать функцию CoCreateInstance с интерфейсом ITfLangBarMgr.
    Как это реализовать на ассемблере?
     
  2. baldr

    baldr New Member

    Публикаций:
    0
    Регистрация:
    29 апр 2010
    Сообщения:
    327
    gale1238,

    Слишком общó. Какой ассемблер, что из инклюдов есть, ну и т.д.
     
  3. gale1238

    gale1238 New Member

    Публикаций:
    0
    Регистрация:
    21 мар 2009
    Сообщения:
    72
    baldr
    Код (Text):
    1. invoke CoCreateInstance,CLSID_TF_LangBarMgr,NULL,CLSCTX_INPROC_SERVER,IID_ITfLangBarMgr,(не знаю)
    Ругается на CLSID_TF_LangBarMgr и IID_ITfLangBarMgr (undefined symbol).
     
  4. gale1238

    gale1238 New Member

    Публикаций:
    0
    Регистрация:
    21 мар 2009
    Сообщения:
    72
    Код (Text):
    1. .386
    2. .model flat,stdcall
    3. option casemap:none
    4.  
    5. include \masm32\include\windows.inc
    6. include \masm32\include\kernel32.inc
    7. include \masm32\include\ole32.inc
    8. includelib \masm32\lib\kernel32.lib
    9. includelib \masm32\lib\ole32.lib
    10.  
    11. .data?
    12.     pUnk dd ?
    13. .const
    14.     cls GUID <0ebb08c45h,06c4ah,04fdch,<0aeh,053h,04eh,0b8h,0c4h,0c7h,0dbh,08eh>>
    15.     iid GUID <087955690h,0e627h,011d2h,<08h,0ddh,00h,010h,05ah,027h,099h,0b5h>>
    16. .code
    17. start:
    18.     invoke CoCreateInstance,offset cls,NULL,CLSCTX_INPROC_SERVER,offset iid,offset pUnk
    19.     invoke ExitProcess,NULL
    20. end start
    Удивительно, что функция CoCreateInstance не вернула ни одного из значений:
    S_OK, REGDB_E_CLASSNOTREG, CLASS_E_NOAGGREGATION, E_NOINTERFACE, E_POINTER.
     
  5. baldr

    baldr New Member

    Публикаций:
    0
    Регистрация:
    29 апр 2010
    Сообщения:
    327
    gale1238,

    Естественно, CO_E_NOTINITIALIZED. Кто CoInitialize() вызывать будет?
     
  6. gale1238

    gale1238 New Member

    Публикаций:
    0
    Регистрация:
    21 мар 2009
    Сообщения:
    72
    Добавил
    Код (Text):
    1. invoke CoInitialize,NULL
    возвращает ошибку E_NOINTERFACE
     
  7. baldr

    baldr New Member

    Публикаций:
    0
    Регистрация:
    29 апр 2010
    Сообщения:
    327
    Значит, так оно и есть. Я в своём реестре (XP SP2) тоже не нашёл регистрации класса {ebb08c45-6c4a-4fdc-ae534eb8c4c7db8e}.
     
  8. gale1238

    gale1238 New Member

    Публикаций:
    0
    Регистрация:
    21 мар 2009
    Сообщения:
    72
    У меня в реестре есть эта ветвь. Если её удалить, то получишь ошибку REGDB_E_CLASSNOTREG.
    Настраивая визуальные эффекты, языковая панель исчезает и появляется, причём ctfmon остаётся в списке запущенных процессов. Значит, задача имеет решение.
     
  9. baldr

    baldr New Member

    Публикаций:
    0
    Регистрация:
    29 апр 2010
    Сообщения:
    327
    msctf.dll экспортирует TF_CreateLangBarMgr(). Она, вроде, работает (без всяких CoInitialize(), методы интерфейса я не трогал).

    Кстати, iid не совсем правильный: не <08h,0ddh,00h, а <08dh,0dbh,00h, — это я подглядел в msctf.dll.
     
  10. gale1238

    gale1238 New Member

    Публикаций:
    0
    Регистрация:
    21 мар 2009
    Сообщения:
    72
    baldr
    Из-за невнимательности указал неверный iid. Сейчас функция возвращает S_OK.
    Следующая строчка на си выглядит приблизительно так:
    Код (Text):
    1. pUnk->ShowFloating(TF_SFT_HIDDEN)
    Не знаю как её записать на ассемблере.
     
  11. baldr

    baldr New Member

    Публикаций:
    0
    Регистрация:
    29 апр 2010
    Сообщения:
    327
    Указатель на интерфейс ссылается на dword с адресом таблицы адресов методов интерфейса. Первые три из IUnknown, остальные согласно ITfLangBarMgr. Т.е. что-то вроде
    Код (Text):
    1.     push    TF_SFT_HIDDEN   ; dwFlags
    2.     mov eax, [pUnk]
    3.     push    eax     ; this
    4.     mov eax, [eax]
    5.     call    [eax+40]    ; Vtbl.ShowFloating
     
  12. gale1238

    gale1238 New Member

    Публикаций:
    0
    Регистрация:
    21 мар 2009
    Сообщения:
    72
    baldr
    Код (Text):
    1. .const
    2.     LibName db "msctf.dll",0
    3.     FunctionName db "TF_CreateLangBarMgr",0
    4. .code
    5. start:
    6.     invoke LoadLibrary,addr LibName
    7.     invoke GetProcAddress,eax,addr FunctionName
    8.     mov eax,[eax]
    9.     call eax
    10.     invoke ExitProcess,NULL
    11. end start
    Ошибка при запуске.
     
  13. baldr

    baldr New Member

    Публикаций:
    0
    Регистрация:
    29 апр 2010
    Сообщения:
    327
    gale1238,

    Естественно, ошибка. Какое отношение первый dword (почти наверняка 0x8b55ff8b) функции TF_CreateLangBarMgr() имеет к тому, что я написал про вызов метода интерфейса COM-объекта? Это про использование значения (указателя на ITfLangBarMgr), которое вызов этой функции возвращает.
     
  14. gale1238

    gale1238 New Member

    Публикаций:
    0
    Регистрация:
    21 мар 2009
    Сообщения:
    72
    baldr
    Пытаюсь получить указатель на интерфейс, запуская функцию TF_CreateLangBarMgr из dll'ки
    без инициализации COM-объекта. Нет желания связываться с реестром. Если можете, помогите, пожалуйста.
     
  15. baldr

    baldr New Member

    Публикаций:
    0
    Регистрация:
    29 апр 2010
    Сообщения:
    327
    Вроде всё уже есть:
    Код (Text):
    1.         format  PE GUI
    2.         include "Win32A.Inc"
    3.  
    4. interface ITfLangBarMgr,\
    5.         QueryInterface,\; IUnknown
    6.         AddRef,\
    7.         Release,\
    8.         AdviseEventSink,\; ITfLangBarMgr
    9.         UnadviseEventSink,\
    10.         GetThreadMarshalInterface,\
    11.         GetThreadLangBarItemMgr,\
    12.         GetInputProcessorProfiles,\
    13.         RestoreLastFocus,\
    14.         SetModalInput,\
    15.         ShowFloating,\
    16.         GetShowFloatingStatus
    17.  
    18. define TF_SFT_SHOWNORMAL               0x00000001
    19. define TF_SFT_DOCK                     0x00000002
    20. define TF_SFT_MINIMIZED                0x00000004
    21. define TF_SFT_HIDDEN                   0x00000008
    22. define TF_SFT_NOTRANSPARENCY           0x00000010
    23. define TF_SFT_LOWTRANSPARENCY          0x00000020
    24. define TF_SFT_HIGHTRANSPARENCY         0x00000040
    25. define TF_SFT_LABELS                   0x00000080
    26. define TF_SFT_NOLABELS                 0x00000100
    27. define TF_SFT_EXTRAICONSONMINIMIZED    0x00000200
    28. define TF_SFT_NOEXTRAICONSONMINIMIZED  0x00000400
    29. define TF_SFT_DESKBAND                 0x00000800
    30.  
    31. ; Здесь всё начинается…
    32.         invoke  TF_CreateLangBarMgr, LangBarMgr
    33.         cominvk LangBarMgr, ShowFloating, TF_SFT_HIDDEN
    34.         cominvk LangBarMgr, Release
    35. ; Вот вроде и всё.
    36.         ret
    37.  
    38. LangBarMgr ITfLangBarMgr
    39.  
    40.         data import
    41.         library MSCTF, "MSCTF.DLL"
    42.         import  MSCTF, TF_CreateLangBarMgr, "TF_CreateLangBarMgr"
    43.         end data
    Это для FASM. Код простой: вызвать TF_CreateLangBarMgr(&LangBarMgr), потом вызвать LangBarMgr->ShowFloating(TF_SFT_HIDDEN), ну и LangBarMgr->Release(). Остальное — обвязка (data import вместо LoadLibrary()/GetProcAddress(), макрос interface чтобы не высчитывать смещение ShowFloating(), макрос cominvk развёртывается в то, что я привёл ранее).
     
  16. gale1238

    gale1238 New Member

    Публикаций:
    0
    Регистрация:
    21 мар 2009
    Сообщения:
    72
    Вот бы переделать её на MASM...
     
  17. baldr

    baldr New Member

    Публикаций:
    0
    Регистрация:
    29 апр 2010
    Сообщения:
    327
    Разве можно так лениться? :derisive:
    Код (Text):
    1.     invoke  LoadLibrary, addr LibName
    2.     invoke  GetProcAddress, eax, addr FunctionName
    3.     push    offset LangBarMgr
    4.     call    eax
    5.     push    8       ; TF_SFT_HIDDEN
    6.     mov ebx, [LangBarMgr]
    7.     push    ebx     ; this
    8.     mov esi, [ebx]
    9.     call    near ptr [esi+40]; Vtbl.ShowFloating
    10.     push    ebx     ; this
    11.     call    near ptr [esi+8]; Vtbl.Release
     
  18. gale1238

    gale1238 New Member

    Публикаций:
    0
    Регистрация:
    21 мар 2009
    Сообщения:
    72
    baldr,
    спасибо за помощь.
    Хочу оформить в в виде процедуры.
    Код (Text):
    1. .const
    2.     LibName db "msctf.dll",0
    3.     FunctionName db "TF_CreateLangBarMgr",0
    4. .code  
    5.     LangBar proc
    6.             local hMSCTF:dword
    7.         local ppv:dword
    8.         invoke LoadLibrary,addr LibName
    9.         mov hMSCTF,eax
    10.         invoke GetProcAddress,eax,addr FunctionName
    11.         push [ppv]  ;push offset ppv не компилируется
    12.         call eax    ;здесь зависает
    13.         ..........................
    14.         invoke FreeLibrary,hMSCTF
    15.         ret
    16.     LangBar endp
    17. .code
    18. start:
    19.     call LangBar
    20.     invoke ExitProcess,NULL
    21. end start
     
  19. shoo

    shoo New Member

    Публикаций:
    0
    Регистрация:
    17 июл 2003
    Сообщения:
    1.537
    Адрес:
    Ukraine
    lea ecx,ppv
    push ecx
     
  20. gale1238

    gale1238 New Member

    Публикаций:
    0
    Регистрация:
    21 мар 2009
    Сообщения:
    72
    Когда языковая панель прячется, то одновременно полоса панели задач становится уже на 2 пикселя.
    Чтобы вернуть размер прямоугольнику делаю следующее:
    Код (Text):
    1. invoke SystemParametersInfo,SPI_GETWORKAREA,0,addr pRect,SPIF_UPDATEINIFILE or SPIF_SENDCHANGE
    2. dec pRect.bottom
    3. invoke SystemParametersInfo,SPI_SETWORKAREA,0,addr pRect,SPIF_UPDATEINIFILE or SPIF_SENDCHANGE
    Но вначале нужно обязательно восстановить языковую панель.
    Может есть другой способ, не такой топорный?