Это похоже на другие ответы, однако обновленные для новой доступной apis и намного более чистые. Кроме того, не предполагается, что вы находитесь в Контексте активности.
public class MyService extends AnyContextSubclass {
public void postToastMessage(final String message) {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(getContext(), message, Toast.LENGTH_LONG).show();
}
});
}
}
Я использую этот метод, и теперь он работает:
if ( IsWindow( hwnd ) )
{
DWORD dwStyle = GetWindowLongPtr( hwnd, GWL_STYLE ) ;
DWORD dwExStyle = GetWindowLongPtr( hwnd, GWL_EXSTYLE ) ;
HMENU menu = GetMenu( hwnd ) ;
RECT rc = { 0, 0, width, height } ;
AdjustWindowRectEx( &rc, dwStyle, menu ? TRUE : FALSE, dwExStyle );
SetWindowPos( hwnd, NULL, 0, 0, rc.right - rc.left, rc.bottom - rc.top, SWP_NOZORDER | SWP_NOMOVE ) ;
}
Я все еще не думаю, что вы предоставили достаточно информации для решения своей проблемы, но вот полная программа, которая делает (в основном) то, что вы хотите. Вы можете сравнить его с вашим, чтобы увидеть, где вы ошибетесь.
#include <Windows.h>
LRESULT CALLBACK WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
switch( uMsg ) {
case WM_CLOSE:
PostQuitMessage( 0 );
break;
case WM_PAINT:
{
RECT clientArea;
GetClientRect( hwnd, &clientArea );
PAINTSTRUCT ps;
BeginPaint( hwnd, &ps );
HBRUSH brush = (HBRUSH)GetStockObject( BLACK_BRUSH );
RECT topLeft = clientArea;
topLeft.right /= 2;
topLeft.bottom /= 2;
RECT bottomRight = clientArea;
bottomRight.left = bottomRight.right / 2;
bottomRight.top = bottomRight.bottom / 2;
FillRect( ps.hdc, &topLeft, brush );
FillRect( ps.hdc, &bottomRight, brush );
EndPaint( hwnd, &ps );
}
return 0;
}
return DefWindowProc( hwnd, uMsg, wParam, lParam );
}
int CALLBACK WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
// Error checking omitted for brevity.
WNDCLASSEX wc = { 0 };
wc.cbSize = sizeof( wc );
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszClassName = L"testclass";
ATOM classAtom = RegisterClassEx( &wc );
HWND window = CreateWindow( L"testclass", L"Test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 480, 240, NULL, NULL, hInstance, NULL );
MSG msg;
while( GetMessage( &msg, NULL, 0, 0 ) ) {
TranslateMessage( &msg );
DispatchMessage( &msg );
}
}
Изменить
После повторного чтения вашего вопроса, я думаю, вы просто ищете AdjustWindowRect API. В этом случае ваш вопрос является дубликатом этого: WinAPI: создайте окно с указанным размером клиентской области . Для дальнейшего использования «область, которую вы можете нарисовать» называется клиентской областью.
Так же, как @Deukalion, я случайно поместил желаемый размер клиентской области в вызов ::CreateWindow()
, и, рисовая сетку, я оказался не в пикселях. Я применил тот же подход к исследованию размера пикселя скриншота моего приложения. Я мог понять, что границы окна и заголовок отбирают какую-то комнату из клиентской области, но разочарование заключается в том, что в Windows 10 даже не имеет общего размера окна приложения!
Я подозреваю, что ::CreateWindow()
вычисляет меньшую клиентскую область путем вычитания жестко заданного количества пикселей по ширине и высоте, а затем создает границу окна и строку заголовка вокруг этого. Это жестко запрограммированное число больше не подходит для ультратонкой темы для Windows. Это смешно - на экране размером с ::CreateWindow()
!
Я следовал совету @PeterRuderman, чтобы использовать вызов ::AdjustWindowRect()
:
RECT rect;
rect.left = rect.top = 0;
rect.right = clientWidth;
rect.bottom = clientHeight;
::AdjustWindowRect(&rect, wflags, false);
HWND hWindow = ::CreateWindow(wcName, title, wflags, 0, 0,
rect.right - rect.left, rect.bottom - rect.top, 0, 0, hInstance, 0);
right
и bottom
как вне предполагаемого прямоугольника. ::AdjustWindowRect()
оставил исходные координаты (0,0) неповрежденными, так что right
и bottom
могут быть непосредственно заполнены в вызов ::CreateWindow()
. Но, к моему удивлению, поля left
и bottom
стали отрицательными.