Не подскажете как перерисовать окно. А именно окошко которое как видно в коде создаётся в приложении при нажатии на левую кнопку мышки (WM_LBUTTONDOWN) которое в свою очередь показывает картинку файл которого например как у меня в коде перетаскивается мышкой в окно приложения при помощи команды (WM_DROPFILES) Картинка показывается нормально только она не перерисованная, то есть при некоторых обстоятельствах (например зону картинки закроет другое окно) картинка исчезает. То есть зону картинки нужно перерисовать. Насколько я знаю это делается например с помощью фукнкции InvalidateRect. А вот как именно с этим у меня тормоза Подскажите пожалуйста. Код (Text): .if uMsg == WM_DROPFILES invoke DragQueryFile,wParam,0,addr buffer,sizeof buffer invoke MultiByteToWideChar,0,0,addr buffer,-1,addr Unicod,addr Char invoke GdipLoadImageFromFile,addr Unicod, addr hImag invoke GdipGetImageWidth, hImag, addr sWidth invoke GdipGetImageHeight, hImag, addr sHeight .elseif uMsg == WM_LBUTTONDOWN invoke DestroyWindow,hGif invoke CreateWindowEx,0,addr Static,0,WS_CHILD,50,50,sWidth,sHeight,hWinFun,0,0,0 mov hGif,eax invoke ShowWindow,hGif,SW_SHOWNORMAL invoke UpdateWindow,hGif invoke GetDC, hGif mov hDC, eax invoke GdipCreateFromHDC, hDC, addr pGraphics invoke GdipDrawImage, pGraphics,hImag,0,0
InvalidateRect инициирует отправку окну сообщения WM_PAINT, которое должно обрабатывать ваше приложение, и перерисовывать окно. Сама собой картинка не перерисуется. WM_PAINT автоматически отправляется системой при необходимости отрисовки участка (или всего окна). Оно поступает через функцию GetMessage, а далее функцией DispatchMessage передаётся обработчику окна. Вы должны установить обработчик сообщения для вашего Static окошка, например функцией SetWindowProc (или создавать окно на основе вашего собственного класса, для которого будет задан ваш обработчик), и написать в нём что-то вроде этого: Код (Text): .elseif uMsg == WM_PAINT // рисуем картинку больше нигде рисовать не нужно, окно должно само себя рисовать.
Если я в коде в конце поставлю функцию InvalidateRect Код (Text): invoke GetDC, hGif mov hDC, eax invoke GdipCreateFromHDC, hDC, addr pGraphics invoke GdipDrawImage, pGraphics,hImag,0,0 Invoke InvalidateRect,hGif,0,TRUE То картинка исчезает сразу
Так и должно быть . InvalidateRect отправляет сообщение WM_PAINT стандартному обработчику класса Static, который в свою очередь рисует пустой статик. upd. Ошибся с функцией, давно на WinAPI не писал. Функция SetWindowLong с параметром GWL_WNDPROC. Причём, если вы хотите сохранить функциональность статика, то после обработки нужных вам сообщений, вы должны передать сообщение стандартному обработчику, иначе ничего кроме отрисовки картинки ваше окно делать не будет.
Не подскажите как и где именно воткнуть функцию SetWindowLong Она имеет три параметра Invoke SetWindowLong,hGif,?,? Первый я так понимаю хендл окошка (hGif) Вторым параметром идёт одно из этих значений GWL_EXSTYLE GWL_HINSTANCE GWL_ID GWL_STYLE GWL_USERDATA GWL_WNDPROC А третий параметр без понятия Подскажите пожалуйста Или это "чудо действие" с окошком класса Static проделать не удастся.
А далее идёт адрес вашей процедуры обработки сообщений, аналогичной процедуре для главного окна, с тем отличием, что необработанные сообщения она передаёт другой функции. У Iczelion'a есть примеры. Invoke SetWindowLong,hGif,GWL_WNDPROC, offset MyStaticProc воткнуть можно сразу после создания статика Код (Text): LRESULT CALLBACK WindowProc( __in HWND hwnd, __in UINT uMsg, __in WPARAM wParam, __in LPARAM lParam ); Код (Text): MyStaticProc: ... .if uMsg == WM_PAINT // рисуем окно ... .else DefWindowProc, hWnd, uMsg, wParam, lParam ... Для более сложных случаев, вместо DefWindowProc, используется функция CallWindowProc
Спасибо dinoweb Попробую разобратся Попробую также посмотреть урок Iczelion'a Надеюсь эти уроки находятся на этом сайте
Просто поставить Код (Text): invoke UpdateWindow,hGif Не пойдёт Спасибо dinoweb подсказал как надо (В данном случае у окошка класса "Static" поменять оконную процедуру при помощи функции SetWindowLong) Код (Text): Invoke SetWindowLong,hGif,GWL_WNDPROC, offset MyStaticProc
assch если вы юзаете static control то он может и сам все делать с картинками и ничего не нужно самому рисовать (собственно для этого и есть контролы,) STM_SETIMAGE установит контролу новый битмап и вы спокойно забываете об этом всем...А извраты с сабклассингом - на любителя. Можете сами рисовать себе на "обычном" окне... Код (Text): ... WM_PAINT: hDC = BeginPaint( hWnd, &ps ); BitBlt( hDC,.., hImgDC, 0, 0); //can use StratchBlt(); EndPaint( &ps ); break; WM_CREATE: hDC = GetDC( hWnd ); hImgDC = CreateCOmpatibleDC( hDC ); ReleaseDC( hWnd, hDC ); break; WM_DROPFILES: SelectObject( hImgDC, NewImageHandle ); GetObject( NewImageHandle, sizeof(BITMAP), &bmp ); rect.left = 0; rect.top = 0; rect.right = bmp.width; rect.bottom = bmp.height; InvalidateRect( hWnd, &rect, FALSE ); .... чот вроде этого..
ASMatic Спасибо за отзыв. Только я попробывал и у меня не чего не получилось. Может я не правильно использовал . invoke SendMessage, hGif, STM_SETIMAGE, hImag, 0 Не туда поставил или параметры не те или вообще не правильно понял вас насчёт STM_SETIMAGE (это я имею в виду если использовать static control ) Не подскажете. Код (Text): .if uMsg == WM_DROPFILES invoke DragQueryFile,wParam,0,addr buffer,sizeof buffer invoke GdipDisposeImage,hImag invoke MultiByteToWideChar,0,0,addr buffer,-1,addr Unicod,addr Char invoke GdipLoadImageFromFile,addr Unicod, addr hImag invoke GdipGetImageWidth, hImag, addr sWidth invoke GdipGetImageHeight, hImag, addr sHeight invoke DestroyWindow,hGif invoke CreateWindowEx,0,addr Static,0,WS_CHILD,50,50,sWidth,sHeight,hWin,0,0,0 mov hGif,eax invoke ShowWindow,hGif,SW_SHOWNORMAL invoke UpdateWindow,hGif invoke GetDC, hGif mov hDC, eax invoke GdipCreateFromHDC, hDC, addr pGraphics invoke GdipDrawImage, pGraphics,hImag,0,0 invoke SendMessage, hGif, STM_SETIMAGE, hImag, 0 ;??????????
Попробуй ка так. Код (Text): invoke CreateWindowEx,0,addr Static,0,5000010Eh,50,50,sWidth,sHeight,hWin,0,0,0 и ещё просмотрел Код (Text): invoke SendMessage,[hGif],STM_SETIMAGE,IMAGE_BITMAP,[hImag]
прежде чем слать STM_SETIMAGE, проверь на валидность hImag и hGif. И убедись, что статик виден (WS_VISIBLE и можно обойтись без ShowWindow/UpdateWindow). И предпоследний параметр CreateWindowEx неплохо бы указать, а не просто ноль.
Статик виден картинка тоже только не перерисовывается Код (Text): .if uMsg == WM_DROPFILES invoke DragQueryFile,wParam,0,addr buffer,sizeof buffer invoke GdipDisposeImage,hImag invoke MultiByteToWideChar,0,0,addr buffer,-1,addr Unicod,addr Char invoke GdipLoadImageFromFile,addr Unicod, addr hImag invoke GdipGetImageWidth, hImag, addr sWidth invoke GdipGetImageHeight, hImag, addr sHeight invoke DestroyWindow,hGif invoke CreateWindowEx,0,addr Static,0,WS_CHILD,50,50,sWidth,sHeight,hWin,0,0,0 mov hGif,eax invoke ShowWindow,hGif,SW_SHOWNORMAL invoke UpdateWindow,hGif invoke GetDC, hGif mov hDC, eax invoke GdipCreateFromHDC, hDC, addr pGraphics invoke GdipDrawImage, pGraphics,hImag,0,0 invoke SendMessage,hGif,STM_SETIMAGE,IMAGE_BITMAP,hImag
Так зачем вы рисуете, если решили переложить эту работу на стандартный функционал класса? Статик сам всё нарисует. Код (Text): #define SS_BITMAP 14 Код (Text): invoke CreateWindowEx,0,addr Static,0,WS_CHILD|SS_BITMAP,50,50,sWidth,sHeight,hWin,0,0,0 И ещё - функция GdipLoadImageFromFile загружает НЕ IMAGE_BITMAP, поэтому hImag не подоходит в качестве параметра для STM_SETIMAGE