Создание окон в отдельных потоках

Тема в разделе "WASM.WIN32", создана пользователем UTeX, 24 янв 2008.

  1. UTeX

    UTeX New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2007
    Сообщения:
    584
    Нужна вот помощь такого плана
    Хочу код сделать такой чтобы можно было создавать окно в отдельном потоке
    И например вызывать в таком виде

    Код (Text):
    1. int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
    2. {
    3.     WNDGENERIC WndPrm;
    4.     CXWndParamsOverlapped(&WndPrm, 0, 0, L"CXWndClass", L"CXWndTest", GetModuleHandle(0), 0, OWN_THREAD, 10, 10, 100, 100);
    5.     CXWnd *MainWindow = new CXWnd(&WndPrm);
    6.     CXWndParamsOverlapped(&WndPrm, 0, 0, L"CXWndClass1", L"CXWndTest1", GetModuleHandle(0), 0, OWN_THREAD, 10, 10, 100, 100);
    7.     CXWnd *MainWindow1 = new CXWnd(&WndPrm);
    8.     delete MainWindow;
    9.     delete MainWindow1;
    10.     return 0;
    11. }
    Но тут недостаток большой что мой код ожидает завершения потока с MainWindow и только потом содает новое окно

    Судя по тому что реализовано в VCL Application->Run() кажется что именно тут и встроено ожидание сигнального состояния для всех потоков

    Есть ли возможность сделать это иначе?
    Я уже некоторых людей затрахивал подомным вопросом - так что простите если кого напрягал - сюда запостил т к решения не нашел

    вот код что есть

    Код (Text):
    1. #ifndef __ABSTRACTH
    2. #define __ABSTRACTH
    3. #include<windows.h>
    4. typedef struct _SIZES
    5. {
    6.     DWORD X;
    7.     DWORD Y;
    8.     DWORD Width;
    9.     DWORD Height;
    10. }SIZES,
    11. *PSIZES;
    12. typedef struct _WNDGENERIC
    13. {
    14.     DWORD GenStyle;
    15.     DWORD ExtraStyle;
    16.     DWORD ID;
    17.     PWCHAR ClassName;
    18.     PWCHAR WindowName;
    19.     HINSTANCE Instance;
    20.     HWND Parent;
    21.     BOOL OwnsAThread;
    22.     SIZES WndSize;
    23. }WNDGENERIC,
    24. *PWNDGENERIC;
    25. typedef enum _RSRC
    26. {
    27.     RSRC_BMP = 0,  
    28.     RSRC_JPG = 1,
    29.     RSRC_GIF = 2,
    30.     RSRC_PNG = 3,
    31.     RSRC_CUR = 4,
    32.     RSRC_ICO = 5
    33. }RSRC;
    34. typedef struct _WNDRESOURCE
    35. {
    36.     BOOL External;
    37.     //external
    38.     PWCHAR Name;//resource name if external
    39.     RSRC ResourceType;//resource type
    40.     DWORD ResourceID;//if from resources
    41.     //internal
    42.     DWORD Color;//color
    43.     HRGN Region;//region
    44. }WNDRESOURCE,
    45. *PWNDRESOURCE;
    46. //unifying resources
    47. class WinXResourceContainer
    48. {
    49. private:
    50.     PWNDRESOURCE Rsrc;
    51. public:
    52.     WinXResourceContainer(PWNDRESOURCE Rsrc);
    53.     BOOL MakeOperation(/*operation*/){};
    54.     ~WinXResourceContainer();
    55. };
    56. #endif
    Код (Text):
    1. #ifndef __CXWND
    2. #define __CXWND
    3. #include"Abstract.h"
    4. #include<windows.h>
    5. #define OWN_THREAD 1
    6. #define THIS_CONTEXT 0
    7. class CXWnd
    8. {
    9. private:
    10.     WNDGENERIC Params;
    11.     MSG Msg;
    12.     HANDLE WndThread;
    13.     HWND WndHandle;
    14.     void Destroy();
    15.     void Show(UINT Show);
    16.     DWORD MessageDispatch();
    17.     friend DWORD Create(CXWnd *WndObj);
    18.     friend LRESULT __stdcall CXWndProc(HWND  , UINT msg, LPARAM lparam, WPARAM wparam);
    19. public:
    20.     BOOL SetRegionResource(PWNDRESOURCE Rsrc);
    21.     BOOL SetPosition(PSIZES Pstn);
    22.     BOOL SetName(PWCHAR Name);
    23.     HWND GetHWND();
    24.     HANDLE GetThreadHandle();
    25.     CXWnd(PWNDGENERIC Params);
    26.     ~CXWnd();
    27. };
    28. void __forceinline CXWndParamsOverlapped(PWNDGENERIC Prm,
    29.                                     DWORD ExtraStyle,
    30.                                     DWORD ID,
    31.                                     PWCHAR ClassName,
    32.                                     PWCHAR WindowName,
    33.                                     HINSTANCE Instance,
    34.                                     HWND Parent,
    35.                                     BOOL OwnsAThread,
    36.                                     DWORD X,
    37.                                     DWORD Y,
    38.                                     DWORD H,
    39.                                     DWORD W)
    40. {
    41.     Prm->GenStyle = WS_OVERLAPPEDWINDOW;
    42.     Prm->ClassName = ClassName;
    43.     Prm->ExtraStyle = ExtraStyle;
    44.     Prm->ID = ID;
    45.     Prm->Instance = Instance;
    46.     Prm->OwnsAThread = OwnsAThread;
    47.     Prm->Parent = Parent;
    48.     Prm->WindowName = WindowName;
    49.     Prm->WndSize.X = X;
    50.     Prm->WndSize.Y = Y;
    51.     Prm->WndSize.Height = H;
    52.     Prm->WndSize.Width = W;
    53. }
    54.  
    55. #endif
    и реализация

    Код (Text):
    1. #include"CXWnd.h"
    2. #include<windows.h>
    3. LRESULT __stdcall CXWndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
    4. {
    5.     switch(msg)
    6.     {
    7.     case WM_CREATE:
    8.         {
    9.             return 0;
    10.         }
    11.     case WM_PAINT:
    12.         {
    13.             PAINTSTRUCT ps;
    14.             HDC dc;
    15.  
    16.             dc = BeginPaint(hwnd, &ps);
    17.             EndPaint(hwnd, &ps);
    18.             return 0;
    19.         }
    20.     case WM_CLOSE:
    21.         {
    22.             DestroyWindow(hwnd);
    23.             return 0;
    24.         }
    25.     case WM_DESTROY:
    26.         {
    27.             PostMessage(hwnd, WM_QUIT, 0, 0);
    28.             return 0;
    29.         }
    30.     }
    31.     return DefWindowProc(hwnd, msg, wparam, lparam);
    32. }
    33. DWORD CXWnd::MessageDispatch()
    34. {
    35.     DWORD Ret;
    36.     while(TRUE)
    37.     {
    38.         Ret = GetMessage(&Msg, 0, 0, 0);
    39.         if(Ret==-1)
    40.             return -1;
    41.         else if(!Ret)
    42.             break;
    43.         else
    44.         {
    45.             TranslateMessage(&Msg);
    46.             DispatchMessage(&Msg);
    47.         }
    48.     }
    49.     return (WPARAM)Msg.wParam;
    50. }
    51. void CXWnd::Show(UINT Show)
    52. {
    53.     if(Params.OwnsAThread)
    54.         ::ShowWindowAsync(WndHandle, Show);
    55.     else
    56.         ::ShowWindow(WndHandle, Show);
    57.     UpdateWindow(WndHandle);
    58. }
    59. DWORD Create(CXWnd *WndObj)
    60. {
    61.     WNDCLASSEXW wc;
    62.     DWORD Ret;
    63.     RtlZeroMemory(&wc, sizeof(wc));
    64.     wc.cbSize = sizeof(wc);
    65.     wc.hInstance = WndObj->Params.Instance;
    66.     wc.lpszClassName = WndObj->Params.ClassName;
    67.     wc.style = CS_HREDRAW|CS_VREDRAW;
    68.     wc.lpfnWndProc = CXWndProc;
    69.     wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    70.     wc.hIcon = LoadIcon(0, IDI_APPLICATION);
    71.     wc.hIconSm = wc.hIcon;
    72.     wc.hCursor = LoadCursor(0, IDC_ARROW);
    73.     if(!RegisterClassEx(&wc))
    74.         return -1;
    75.     WndObj->WndHandle = CreateWindowEx(WndObj->Params.ExtraStyle,
    76.                                 WndObj->Params.ClassName,
    77.                                 WndObj->Params.WindowName,
    78.                                 WndObj->Params.GenStyle,
    79.                                 WndObj->Params.WndSize.X,
    80.                                 WndObj->Params.WndSize.Y,
    81.                                 WndObj->Params.WndSize.Width,
    82.                                 WndObj->Params.WndSize.Height,
    83.                                 WndObj->Params.Parent,
    84.                                 (HMENU)WndObj->Params.ID,
    85.                                 WndObj->Params.Instance,
    86.                                 0); // think about it!
    87.     if(!WndObj->WndHandle)
    88.         return -1;
    89.     else
    90.     {
    91.         WndObj->Show(SW_SHOWNORMAL);
    92.         ::UpdateWindow(WndObj->WndHandle);
    93.         Ret = WndObj->MessageDispatch();
    94.     }
    95.     return Ret;
    96. }
    97. HWND CXWnd::GetHWND()
    98. {
    99.     return WndHandle;
    100. }
    101. void CXWnd::Destroy()
    102. {
    103.     if(Params.OwnsAThread)
    104.     {
    105.         CloseHandle(WndThread);
    106.     }
    107.     delete []Params.WindowName;
    108.     delete []Params.ClassName;
    109.     RtlZeroMemory(&Params, sizeof(Params));
    110. }
    111. BOOL CXWnd::SetRegionResource(PWNDRESOURCE Rsrc)
    112. {
    113.     return FALSE;
    114. }
    115. BOOL CXWnd::SetPosition(PSIZES Pstn)
    116. {
    117.     return FALSE;
    118. }
    119. BOOL CXWnd::SetName(PWCHAR Name)
    120. {
    121.     PostMessage(WndHandle, WM_SETTEXT, 0, Name);
    122.     return FALSE;
    123. }
    124. HANDLE CXWnd::GetThreadHandle()
    125. {
    126.     return WndThread;
    127. }
    128. CXWnd::CXWnd(PWNDGENERIC InParams)
    129. {
    130.     RtlCopyMemory(&Params, InParams, sizeof WNDGENERIC);
    131.     Params.WindowName = new WCHAR[lstrlenW(InParams->WindowName) + 1];
    132.     RtlCopyMemory(Params.WindowName, InParams->WindowName, (lstrlenW(InParams->WindowName) + 1) * sizeof WCHAR);
    133.     Params.ClassName = new WCHAR[lstrlenW(InParams->ClassName) + 1];
    134.     RtlCopyMemory(Params.ClassName, InParams->ClassName, (lstrlenW(InParams->ClassName) + 1) * sizeof WCHAR);
    135.     if(Params.OwnsAThread)
    136.     {
    137.         WndThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)Create, this, 0, 0);
    138.         if(!WndThread)
    139.             return;
    140.         if(WaitForSingleObject(WndThread, INFINITE)==WAIT_FAILED)
    141.             return;
    142.     }
    143.     else
    144.         Create(this);
    145. }
    146. CXWnd::~CXWnd()
    147. {
    148.     Destroy(); 
    149. }
    З Ы:
    понятное дело что тут все не правильно - подскажите как сделать правильно
     
  2. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Самодельные обёртки? Занимательно.

    Для запуска окна с другого потока ты должен сделать и выборку сообщений в том же потоке. Имхо.
     
  3. UTeX

    UTeX New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2007
    Сообщения:
    584
    чем занимательно то? просто так будет удобнее считаю
    а я разве не так сделал?
     
  4. UTeX

    UTeX New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2007
    Сообщения:
    584
    проблема в том что тут то приходится ждать
     
  5. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    UTeX
    Не так понял вопрос. А в чём проблема, если не ждать? Непонятно, что требуется получить в итоге, VCL не знаю. Если требуется создать несколько окон в отдельных потоках и подождать потом их завершения, то почему бы не создать окна, а ожидать их в отдельной функции, например:
    Код (Text):
    1. ...
    2.  CXWnd *MainWindow1 = new CXWnd(&WndPrm);
    3.  HANDLE wnds[2] = {MainWindow->WndThread, MainWindow1->WndThread};
    4.  WaitForMultipleObjects(2, wnds, TRUE, INFINITE);
    5.  delete MainWindow;
     
  6. UTeX

    UTeX New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2007
    Сообщения:
    584
    Это все верно. Но просто не очень номально как мне кажется если я собираюсь создавать таким же образом например и дочерние окна.
    Поэтому было бы неплохо услышать еще какое-нибудь решение.
     
  7. kero

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

    Публикаций:
    0
    Регистрация:
    4 апр 2006
    Сообщения:
    1.074
    Адрес:
    Москва
    ?
    ----
    Способ не ждать:
    Код (Text):
    1. WinMain proto :DWORD,:DWORD,:DWORD,:DWORD
    2.  
    3. .data
    4.  _class   db "%d_class",0
    5.  _button  db "button",0
    6.  rect     RECT <10,10,90,60>
    7. .data?
    8.  hinst    dd ?
    9.  hwin     dd ?
    10.  count   dd ?
    11.  
    12. .code
    13.  
    14. ThreadProc proc param:DWORD
    15.   invoke WinMain,hinst,0,0,SW_SHOWDEFAULT
    16.   invoke ExitThread,0
    17.   ret
    18. ThreadProc endp
    19.  
    20.  
    21. WndProc proc uses ebx hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
    22.  
    23.   local ps:PAINTSTRUCT
    24.  
    25.   mov eax,hWnd
    26.   .if uMsg==WM_DESTROY
    27.     invoke PostQuitMessage,0
    28.     xor eax,eax
    29.    
    30.   .elseif uMsg==WM_PAINT
    31.     invoke BeginPaint,hWnd,addr ps
    32.     mov ebx,eax
    33.     invoke GetStockObject,BLACK_BRUSH
    34.     invoke FillRect,ebx,addr rect,eax
    35.     invoke EndPaint,hWnd,addr ps
    36.     xor eax,eax
    37.    
    38.   .elseif uMsg==WM_COMMAND && wParam==3000 && eax==hwin
    39.     inc count
    40.     invoke CreateThread,0,0,offset ThreadProc,0,0,0
    41.     invoke CloseHandle,eax
    42.     xor eax,eax
    43.    
    44.   .else
    45.     invoke DefWindowProc,hWnd,uMsg,wParam,lParam
    46.   .endif
    47.   ret
    48. WndProc endp
    49.  
    50.  
    51. WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
    52.   local wc:WNDCLASSEX
    53.   local msg:MSG
    54.   local hWnd:HWND
    55.   local buf[32]:BYTE
    56.  
    57.   mov wc.cbSize,sizeof WNDCLASSEX
    58.   mov wc.style,CS_DBLCLKS
    59.   mov wc.lpfnWndProc,offset WndProc
    60.   mov wc.cbClsExtra,0
    61.   mov wc.cbWndExtra,0
    62.   mov eax,hInst
    63.   mov wc.hInstance,eax
    64.   mov wc.hbrBackground,COLOR_WINDOW
    65.   mov wc.lpszMenuName,0
    66.   invoke LoadIcon,0,IDI_APPLICATION
    67.   mov wc.hIcon,eax
    68.   mov wc.hIconSm,eax
    69.   invoke LoadCursor,0,IDC_HAND
    70.   mov wc.hCursor,eax
    71.  
    72.   invoke wsprintf,addr buf,offset _class,count
    73.   lea eax,buf
    74.   mov wc.lpszClassName,eax
    75.  
    76.   invoke RegisterClassEx,addr wc
    77.  
    78.   mov eax,count
    79.   .if eax==0
    80.     mov ecx,500
    81.   .else
    82.     shl eax,4
    83.     mov ecx,eax
    84.   .endif
    85.   invoke CreateWindowEx,WS_EX_CLIENTEDGE OR WS_EX_TOPMOST OR WS_EX_TOOLWINDOW,addr buf,addr buf,WS_OVERLAPPEDWINDOW,ecx,eax,300,200,0,0,hInst,0
    86.   mov hWnd,eax
    87.   invoke ShowWindow,hWnd,SW_SHOWDEFAULT
    88.   invoke UpdateWindow,hWnd
    89.  
    90. ;  invoke SetWindowLong,hWnd,GWL_USERDATA,count
    91.   .if count==0
    92.     invoke CreateWindowEx,0,addr _button,0,WS_VISIBLE OR WS_CHILD,10,80,80,20,hWnd,3000,hinst,0
    93.     mov eax,hWnd
    94.     mov hwin,eax
    95.   .endif
    96.  
    97.   .while TRUE
    98.     invoke GetMessage,addr msg,0,0,0
    99.     .break .if (!eax)
    100.     invoke TranslateMessage,addr msg
    101.     invoke DispatchMessage,addr msg
    102.   .endw
    103.   mov eax,msg.wParam
    104.   ret
    105. WinMain endp
    106.  
    107. start:
    108.   invoke GetModuleHandle,0
    109.   mov hinst,eax
    110.   invoke WinMain,eax,0,0,SW_SHOWDEFAULT
    111.   invoke ExitProcess,eax
    112. end start
     
  8. UTeX

    UTeX New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2007
    Сообщения:
    584
    kero

    Архив чего то битый - так что исходник не увидел - но прогу запустил - похоже это то что нужно возможно а возможно и нет
    Перезалий плиз куда нибудь исходник
    на www.everfall.com/paste например
     
  9. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
  10. kero

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

    Публикаций:
    0
    Регистрация:
    4 апр 2006
    Сообщения:
    1.074
    Адрес:
    Москва
    >Архив чего то битый

    Не битый.
    Хинт: васм предпочитает качалки (ReGet, etc).
    Но код добавил, см. взад .
     
  11. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    Концепт: Либо 1 цикл разбора сообщений - фильтрация msg по всем hwnd (если много процедур обработки) - но теряются потоковые сообщения с hwnd=0 (если всё-таки потоки пролеплены к окошкам, каким-то боком)!
    либо каждому потоку по циклу с тем же разбором по hwnd (окон больше, чем 1 на поток и для каждого своя процедура обработки) - ничего не теряется.
    А так вопрос - что будет то в потоках выполняться? Циклы выборки и фильтрации или просто процедуры обработки сообщений? Последнее конечно легче. На стадии инициализации создаём все потоки суспеденными и в нужный момент просто запускаем тот, что нужно, потом снова останавливаем, не уничтожая объек потока (много накладных расходов)!
     
  12. UTeX

    UTeX New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2007
    Сообщения:
    584
    asmfan
    это ведь и так ясно.

    интересно код который я привел кто-то смотрел
    там явно видно то что я пытаюсь сделать

    kero
    Не пойму только каким образом можно избежать создания окна в основном потоке. есть идеи?
    Просто если его каким то образом не зациклить то сделать не удастся?
     
  13. UTeX

    UTeX New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2007
    Сообщения:
    584
    Судя по всему это реально только в таком виде, как я и думал раньше
    т.е. нужно создать процедуру жидания сигнального состояния всех созданных хендлов окна
     
  14. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    UTeX
    Где в твоём коде отдельные потоки в упор не пойму. Где отдельные разные процедуры обработки? Видимо не так всё ясно, как кажется.
     
  15. UTeX

    UTeX New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2007
    Сообщения:
    584
    Код (Text):
    1. DWORD Create(CXWnd *WndObj)
    2. {
    3.     WNDCLASSEXW wc;
    4.     DWORD Ret;
    5.     RtlZeroMemory(&wc, sizeof(wc));
    6.     wc.cbSize = sizeof(wc);
    7.     wc.hInstance = WndObj->Params.Instance;
    8.     wc.lpszClassName = WndObj->Params.ClassName;
    9.     wc.style = CS_HREDRAW|CS_VREDRAW;
    10.     wc.lpfnWndProc = CXWndProc;
    11.     wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    12.     wc.hIcon = LoadIcon(0, IDI_APPLICATION);
    13.     wc.hIconSm = wc.hIcon;
    14.     wc.hCursor = LoadCursor(0, IDC_ARROW);
    15.     if(!RegisterClassEx(&wc))
    16.         return -1;
    17.     WndObj->WndHandle = CreateWindowEx(WndObj->Params.ExtraStyle,
    18.                                 WndObj->Params.ClassName,
    19.                                 WndObj->Params.WindowName,
    20.                                 WndObj->Params.GenStyle,
    21.                                 WndObj->Params.WndSize.X,
    22.                                 WndObj->Params.WndSize.Y,
    23.                                 WndObj->Params.WndSize.Width,
    24.                                 WndObj->Params.WndSize.Height,
    25.                                 WndObj->Params.Parent,
    26.                                 (HMENU)WndObj->Params.ID,
    27.                                 WndObj->Params.Instance,
    28.                                 0); // think about it!
    29.     if(!WndObj->WndHandle)
    30.         return -1;
    31.     else
    32.     {
    33.         WndObj->Show(SW_SHOWNORMAL);
    34.         ::UpdateWindow(WndObj->WndHandle);
    35.         Ret = WndObj->MessageDispatch();
    36.     }
    37.     return Ret;
    38. }
    это код потока
     
  16. UTeX

    UTeX New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2007
    Сообщения:
    584
    пока что одна - она ничего все равно не делает - не в ней суть
    и вообще апочему они должны быть разными?

    вобщем неясность для меня основная не в этом
     
  17. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    А почему Create как friend, а не как static? Ведь работает всё-равно по указателю без прямого обращения к членам. Callback'и я бы вручную устанавливал динамически. Окна все равноправны. Ожидание внутри класса реализовано. Объектов синхронизации наружу не выведено ни эвентов ни хэндлов потоков. А так всё вроде работать будет.
     
  18. kero

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

    Публикаций:
    0
    Регистрация:
    4 апр 2006
    Сообщения:
    1.074
    Адрес:
    Москва
    Да хоть Sleep:

    Код (Text):
    1. .data
    2.  _class   db "MultiMain_%10.10lu",0
    3.  _title   db "%s_%lu",0
    4.  _button  db "button",0
    5.  _help    db "    MultiMain  by  kero      //      Exit:    F12      //      Create  new  window  thread:    F11,    or  any  big  button  of  the  previous  threads    ",0
    6.  rect     RECT <10,10,90,60>
    7.  
    8. .data?
    9.  hinst    dd ?
    10.  
    11. .code
    12.  
    13. MessageLoop proc
    14.   local msg:MSG
    15.   .while TRUE
    16.     invoke GetMessage,addr msg,0,0,0
    17.     .break .if (!eax)
    18.     invoke TranslateMessage,addr msg
    19.     invoke DispatchMessage,addr msg
    20.   .endw
    21.   mov eax,msg.wParam
    22.   ret
    23. MessageLoop endp
    24.  
    25. WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
    26.   local wc:WNDCLASSEX
    27.   local hWnd:HWND
    28.   local buf[32]:BYTE
    29.  
    30.   mov wc.cbSize,sizeof WNDCLASSEX
    31.   mov wc.style,CS_DBLCLKS
    32.   mov wc.lpfnWndProc,offset WndProc
    33.   mov wc.cbClsExtra,0
    34.   mov wc.cbWndExtra,0
    35.   mov eax,hInst
    36.   mov wc.hInstance,eax
    37.   mov wc.lpszMenuName,0
    38.   invoke LoadIcon,0,IDI_APPLICATION
    39.   mov wc.hIcon,eax
    40.   mov wc.hIconSm,eax
    41.   invoke LoadCursor,0,IDC_HAND
    42.   mov wc.hCursor,eax
    43.  
    44.   invoke GetTickCount
    45.   push eax
    46.   push eax
    47.   invoke GetTickCount
    48.   and eax,0ffffh
    49.   pop ecx  
    50.   shl eax,8
    51.   mov al,cl
    52.   invoke CreateSolidBrush,eax
    53.   mov wc.hbrBackground,eax
    54.   pop eax
    55.   invoke wsprintf,addr buf,offset _class,eax
    56.   lea eax,buf
    57.   mov wc.lpszClassName,eax
    58.  
    59.   invoke RegisterClassEx,addr wc
    60.  
    61.   invoke CreateWindowEx,WS_EX_CLIENTEDGE OR WS_EX_TOPMOST OR WS_EX_TOOLWINDOW,addr buf,0,WS_OVERLAPPEDWINDOW,300,0,240,180,0,0,hInst,0
    62.   mov hWnd,eax
    63.   invoke ShowWindow,hWnd,SW_SHOWDEFAULT
    64.   invoke UpdateWindow,hWnd
    65.    
    66.   invoke MessageLoop
    67.   push eax
    68.   invoke UnregisterClass,addr buf,hInst
    69.   pop eax
    70.   ret
    71. WinMain endp
    72.  
    73. SubProc proc hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
    74.   .if uMsg==WM_DESTROY
    75.     invoke DestroyWindow,hWnd
    76.     xor eax,eax
    77.   .else
    78.     invoke GetWindowLong,hWnd,GWL_USERDATA
    79.     invoke CallWindowProc,eax,hWnd,uMsg,wParam,lParam
    80.   .endif
    81.   ret
    82. SubProc endp
    83.  
    84. ThreadProc proc param:DWORD
    85.   invoke WinMain,hinst,0,0,SW_SHOWDEFAULT
    86.   invoke ExitThread,0
    87.   ret
    88. ThreadProc endp
    89.  
    90. WndProc proc uses ebx hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
    91.  
    92.   local ps:PAINTSTRUCT
    93.   local buf[32]:BYTE
    94.  
    95.   mov eax,hWnd
    96.   .if uMsg==WM_DESTROY
    97.     invoke PostQuitMessage,0
    98.     xor eax,eax
    99.    
    100.   .elseif uMsg==WM_CREATE
    101.     invoke CreateWindowEx,0,addr _button,0,WS_VISIBLE OR WS_CHILD, 10,80,80,24,hWnd,3000,hinst,0
    102.     invoke CreateWindowEx,0,addr _button,0,WS_VISIBLE OR WS_CHILD,110,10,40,24,hWnd,3001,hinst,0
    103.     invoke GetClassName,hWnd,addr buf,31    
    104.     mov ebx,hWnd
    105.     jmp @f
    106.  
    107.   .elseif uMsg==WM_COMMAND && wParam==3001
    108.     invoke GetClassName,hWnd,addr buf,31
    109.     invoke CreateWindowEx,WS_EX_CLIENTEDGE OR WS_EX_TOPMOST OR WS_EX_TOOLWINDOW,addr buf,0,WS_OVERLAPPEDWINDOW OR WS_VISIBLE,0,0,210,150,0,0,hinst,0
    110.     mov ebx,eax
    111.     invoke SetWindowLong,ebx,GWL_WNDPROC,addr SubProc
    112.     invoke SetWindowLong,ebx,GWL_USERDATA,eax
    113. @@:
    114.     invoke GetWindowThreadProcessId,ebx,0
    115.     invoke wsprintf,addr buf,offset _title,addr buf,eax
    116.     invoke SetWindowText,ebx,addr buf    
    117.     xor eax,eax
    118.    
    119.   .elseif uMsg==WM_COMMAND && wParam==3000
    120.     invoke CreateThread,0,0,offset ThreadProc,0,0,0
    121.     invoke CloseHandle,eax
    122.     xor eax,eax    
    123.  
    124.   .elseif uMsg==WM_PAINT
    125.     invoke BeginPaint,hWnd,addr ps
    126.     mov ebx,eax
    127.     invoke GetStockObject,BLACK_BRUSH
    128.     invoke FillRect,ebx,addr rect,eax
    129.     invoke GetStockObject,WHITE_BRUSH
    130.     invoke FrameRect,ebx,addr rect,eax
    131.     invoke EndPaint,hWnd,addr ps
    132.     xor eax,eax
    133.    
    134.   .else
    135.     invoke DefWindowProc,hWnd,uMsg,wParam,lParam
    136.   .endif
    137.   ret
    138. WndProc endp
    139.  
    140. ScreenText proc uses ebx lpstr:LPSTR
    141.   invoke MessageBeep,0
    142.   invoke GetDC,0
    143.   mov ebx,eax
    144.   invoke lstrlen,lpstr
    145.   invoke TextOut,ebx,0,0,lpstr,eax
    146.   invoke ReleaseDC,0,ebx
    147.   ret
    148. ScreenText endp
    149.  
    150. start:
    151.   invoke GetModuleHandle,0
    152.   mov hinst,eax
    153.   invoke ScreenText,offset _help
    154. @0:
    155.   invoke Sleep,50
    156.   invoke GetKeyState,VK_F11
    157.   and eax,8000h
    158.   jz @1
    159.   invoke InvalidateRect,0,0,1
    160. @2:
    161.   invoke Sleep,10  ; анти дребезг контактов
    162.   invoke GetKeyState,VK_F11
    163.   and eax,8000h
    164.   jnz @2
    165.   invoke CreateThread,0,0,offset ThreadProc,0,0,0
    166.   invoke CloseHandle,eax
    167. @1:  
    168.   invoke GetKeyState,VK_F12
    169.   and eax,8000h
    170.   jz @0
    171.   invoke MessageBeep,0
    172.   invoke InvalidateRect,0,0,1
    173.   invoke ExitProcess,eax
    174. end start
     
  19. UTeX

    UTeX New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2007
    Сообщения:
    584
    Код (Text):
    1. DWORD Create(CXWnd *WndObj)
    2. {
    3. //...
    4.     WndObj->WndHandle = CreateWindowEx(/*...*/);
    5. //...
    6. }
     
  20. UTeX

    UTeX New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2007
    Сообщения:
    584