📄 gdkwindow-win32.c
字号:
hparent = GDK_WINDOW_HWND (parent); window = g_object_new (GDK_TYPE_WINDOW, NULL); private = (GdkWindowObject *)window; impl = GDK_WINDOW_IMPL_WIN32 (private->impl); draw_impl = GDK_DRAWABLE_IMPL_WIN32 (private->impl); draw_impl->wrapper = GDK_DRAWABLE (window); /* Windows with a foreign parent are treated as if they are children * of the root window, except for actual creation. */ if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_FOREIGN) parent = _gdk_parent_root; private->parent = (GdkWindowObject *)parent; private->accept_focus = TRUE; private->focus_on_map = TRUE; if (attributes_mask & GDK_WA_X) private->x = attributes->x; else private->x = 0; if (attributes_mask & GDK_WA_Y) private->y = attributes->y; else if (attributes_mask & GDK_WA_X) private->y = 100; /* ??? We must put it somewhere... */ else private->y = 0; if (attributes_mask & GDK_WA_VISUAL) visual = attributes->visual; else visual = gdk_visual_get_system (); impl->width = (attributes->width > 1) ? (attributes->width) : (1); impl->height = (attributes->height > 1) ? (attributes->height) : (1); impl->extension_events_selected = FALSE; if (attributes->wclass == GDK_INPUT_ONLY) { /* Backwards compatiblity - we've always ignored * attributes->window_type for input-only windows * before */ if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_ROOT) private->window_type = GDK_WINDOW_TEMP; else private->window_type = GDK_WINDOW_CHILD; } else private->window_type = attributes->window_type; if (attributes->wclass == GDK_INPUT_OUTPUT) { dwExStyle = 0; private->input_only = FALSE; private->depth = visual->depth; if (attributes_mask & GDK_WA_COLORMAP) { draw_impl->colormap = attributes->colormap; g_object_ref (attributes->colormap); } else { draw_impl->colormap = gdk_screen_get_system_colormap (screen); g_object_ref (draw_impl->colormap); } } else { dwExStyle = WS_EX_TRANSPARENT; private->depth = 0; private->input_only = TRUE; draw_impl->colormap = gdk_screen_get_system_colormap (screen); g_object_ref (draw_impl->colormap); GDK_NOTE (MISC, g_print ("...GDK_INPUT_ONLY, system colormap")); } switch (private->window_type) { case GDK_WINDOW_TOPLEVEL: dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN; hparent = _gdk_root_window; offset_x = _gdk_offset_x; offset_y = _gdk_offset_y; break; case GDK_WINDOW_CHILD: dwStyle = WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; break; case GDK_WINDOW_DIALOG: dwStyle = WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU | WS_CAPTION | WS_THICKFRAME | WS_CLIPCHILDREN;#if 0 dwExStyle |= WS_EX_TOPMOST; /* //HB: want this? */#endif hparent = _gdk_root_window; offset_x = _gdk_offset_x; offset_y = _gdk_offset_y; break; case GDK_WINDOW_TEMP: dwStyle = WS_CLIPCHILDREN | WS_CLIPSIBLINGS; /* a temp window is not necessarily a top level window */ dwStyle |= (_gdk_parent_root == parent ? WS_POPUP : WS_CHILDWINDOW); dwExStyle |= WS_EX_TOOLWINDOW; offset_x = _gdk_offset_x; offset_y = _gdk_offset_y; break; case GDK_WINDOW_ROOT: g_error ("cannot make windows of type GDK_WINDOW_ROOT"); break; default: g_assert_not_reached (); } _gdk_window_init_position (GDK_WINDOW (private)); if (private->window_type != GDK_WINDOW_CHILD) { rect.left = rect.top = 0; rect.right = impl->position_info.width; rect.bottom = impl->position_info.height; AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle); window_width = rect.right - rect.left; window_height = rect.bottom - rect.top; } else { window_width = impl->position_info.width; window_height = impl->position_info.height; } if (attributes_mask & GDK_WA_TITLE) title = attributes->title; else title = get_default_title (); if (!title || !*title) title = "GDK client window"; private->event_mask = GDK_STRUCTURE_MASK | attributes->event_mask; if (private->parent) private->parent->children = g_list_prepend (private->parent->children, window); klass = RegisterGdkClass (private->window_type); mbtitle = g_locale_from_utf8 (title, -1, NULL, NULL, NULL); { HWND hwndNew = CreateWindowEx (dwExStyle, MAKEINTRESOURCE(klass), mbtitle, dwStyle, ((attributes_mask & GDK_WA_X) ? impl->position_info.x - offset_x: CW_USEDEFAULT), impl->position_info.y - offset_y, window_width, window_height, hparent, NULL, _gdk_app_hmodule, window); if (GDK_WINDOW_HWND (window) != hwndNew) { g_warning("gdk_window_new: gdk_event_translate::WM_CREATE (%p, %p) HWND mismatch.", GDK_WINDOW_HWND (window), hwndNew); /* HB: IHMO due to a race condition the handle was increased by * one, which causes much trouble. Because I can't find the * real bug, try to workaround it ... * To reproduce: compile with MSVC 5, DEBUG=1 */# if 0 gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window)); GDK_WINDOW_HWND (window) = hwndNew; gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);# else /* the old behaviour, but with warning */ draw_impl->handle = hwndNew;# endif } } g_object_ref (window); gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window); GDK_NOTE (MISC, g_print ("... \"%s\" %dx%d@+%d+%d %p = %p\n", mbtitle, window_width, window_height, ((attributes_mask & GDK_WA_X) ? impl->position_info.x - offset_x: CW_USEDEFAULT), impl->position_info.y - offset_y, hparent, GDK_WINDOW_HWND (window))); g_free (mbtitle); if (draw_impl->handle == NULL) { WIN32_API_FAILED ("CreateWindowEx"); g_object_unref (window); return NULL; } if (!from_set_skip_taskbar_hint && private->window_type == GDK_WINDOW_TEMP) gdk_window_set_skip_taskbar_hint (window, TRUE); gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ? (attributes->cursor) : NULL)); return window;}GdkWindow*gdk_window_new (GdkWindow *parent, GdkWindowAttr *attributes, gint attributes_mask){ return gdk_window_new_internal (parent, attributes, attributes_mask, FALSE);}GdkWindow *gdk_window_foreign_new_for_display (GdkDisplay *display, GdkNativeWindow anid){ GdkWindow *window; GdkWindowObject *private; GdkWindowImplWin32 *impl; GdkDrawableImplWin32 *draw_impl; HANDLE parent; RECT rect; POINT point; g_return_val_if_fail (display == gdk_display_get_default (), NULL); window = g_object_new (GDK_TYPE_WINDOW, NULL); private = (GdkWindowObject *)window; impl = GDK_WINDOW_IMPL_WIN32 (private->impl); draw_impl = GDK_DRAWABLE_IMPL_WIN32 (private->impl); draw_impl->wrapper = GDK_DRAWABLE (window); parent = GetParent ((HWND)anid); private->parent = gdk_win32_handle_table_lookup ((GdkNativeWindow) parent); if (!private->parent || GDK_WINDOW_TYPE (private->parent) == GDK_WINDOW_FOREIGN) private->parent = (GdkWindowObject *)_gdk_parent_root; private->parent->children = g_list_prepend (private->parent->children, window); draw_impl->handle = (HWND) anid; GetClientRect ((HWND) anid, &rect); point.x = rect.left; point.y = rect.right; ClientToScreen ((HWND) anid, &point); if (parent != _gdk_root_window) ScreenToClient (parent, &point); private->x = point.x; private->y = point.y; impl->width = rect.right - rect.left; impl->height = rect.bottom - rect.top; private->window_type = GDK_WINDOW_FOREIGN; private->destroyed = FALSE; private->event_mask = GDK_ALL_EVENTS_MASK; /* XXX */ if (IsWindowVisible ((HWND) anid)) private->state &= (~GDK_WINDOW_STATE_WITHDRAWN); else private->state |= GDK_WINDOW_STATE_WITHDRAWN; if (GetWindowLong ((HWND)anid, GWL_EXSTYLE) & WS_EX_TOPMOST) private->state |= GDK_WINDOW_STATE_ABOVE; else private->state &= (~GDK_WINDOW_STATE_ABOVE); private->state &= (~GDK_WINDOW_STATE_BELOW); private->depth = gdk_visual_get_system ()->depth; _gdk_window_init_position (GDK_WINDOW (private)); g_object_ref (window); gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window); return window;}GdkWindow*gdk_window_lookup (GdkNativeWindow hwnd){ return (GdkWindow*) gdk_win32_handle_table_lookup (hwnd); }void_gdk_windowing_window_destroy (GdkWindow *window, gboolean recursing, gboolean foreign_destroy){ GdkWindowObject *private = (GdkWindowObject *)window; g_return_if_fail (GDK_IS_WINDOW (window)); GDK_NOTE (MISC, g_print ("_gdk_windowing_window_destroy: %p\n", GDK_WINDOW_HWND (window))); if (private->extension_events != 0) _gdk_input_window_destroy (window); if (!recursing && !foreign_destroy) { private->destroyed = TRUE; DestroyWindow (GDK_WINDOW_HWND (window)); } gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));}void_gdk_windowing_window_destroy_foreign (GdkWindow *window){ /* It's somebody else's window, but in our hierarchy, * so reparent it to the root window, and then call * DestroyWindow() on it. */ gdk_window_hide (window); gdk_window_reparent (window, NULL, 0, 0); /* Is this too drastic? Many (most?) applications * quit if any window receives WM_QUIT I think. * OTOH, I don't think foreign windows are much * used, so the question is maybe academic. */ PostMessage (GDK_WINDOW_HWND (window), WM_QUIT, 0, 0);}/* This function is called when the window really gone. */voidgdk_window_destroy_notify (GdkWindow *window){ g_return_if_fail (window != NULL); g_return_if_fail (GDK_IS_WINDOW (window)); GDK_NOTE (EVENTS, g_print ("gdk_window_destroy_notify: %p%s\n", GDK_WINDOW_HWND (window), (GDK_WINDOW_DESTROYED (window) ? " (destroyed)" : ""))); if (!GDK_WINDOW_DESTROYED (window)) { if (GDK_WINDOW_TYPE(window) != GDK_WINDOW_FOREIGN) g_warning ("window %p unexpectedly destroyed", GDK_WINDOW_HWND (window)); _gdk_window_destroy (window, TRUE); } gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window)); g_object_unref (window);}static voidget_outer_rect (GdkWindow *window, gint width, gint height, RECT *rect){ LONG style, exstyle; style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE); exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE); rect->left = rect->top = 0; rect->right = width; rect->bottom = height; API_CALL (AdjustWindowRectEx, (rect, style, FALSE, exstyle));}static voidadjust_for_gravity_hints (GdkWindowImplWin32 *impl, RECT *outer_rect, gint *x, gint *y){ if (impl->hint_flags & GDK_HINT_WIN_GRAVITY) { gint orig_x = *x, orig_y = *y; switch (impl->hints.win_gravity) { case GDK_GRAVITY_NORTH: case GDK_GRAVITY_CENTER: case GDK_GRAVITY_SOUTH: *x -= (outer_rect->right - outer_rect->left) / 2; *x += impl->width / 2; break; case GDK_GRAVITY_SOUTH_EAST: case GDK_GRAVITY_EAST: case GDK_GRAVITY_NORTH_EAST: *x -= outer_rect->right - outer_rect->left; *x += impl->width; break; case GDK_GRAVITY_STATIC: *x += outer_rect->left; break; default: break; } switch (impl->hints.win_gravity) { case GDK_GRAVITY_WEST: case GDK_GRAVITY_CENTER: case GDK_GRAVITY_EAST: *y -= (outer_rect->bottom - outer_rect->top) / 2; *y += impl->height / 2; break; case GDK_GRAVITY_SOUTH_WEST: case GDK_GRAVITY_SOUTH: case GDK_GRAVITY_SOUTH_EAST: *y -= outer_rect->bottom - outer_rect->top; *y += impl->height; break; case GDK_GRAVITY_STATIC: *y += outer_rect->top; break; default: break; } GDK_NOTE (MISC, (orig_x != *x || orig_y != *y) ? g_print ("adjust_for_gravity_hints: x: %d->%d, y: %d->%d\n", orig_x, *x, orig_y, *y) : (void) 0); }}static voidshow_window_internal (GdkWindow *window, gboolean raise, gboolean deiconify){ GdkWindowObject *private; HWND old_active_window; gboolean focus_on_map = TRUE; private = (GdkWindowObject *) window; if (private->destroyed) return; GDK_NOTE (MISC, g_print ("show_window_internal: %p: %s%s%s\n", GDK_WINDOW_HWND (window), _gdk_win32_window_state_to_string (private->state), (raise ? " raise" : ""), (deiconify ? " deiconify" : ""))); /* If asked to show (not deiconify) an withdrawn and iconified * window, do that. */ if (!deiconify && !GDK_WINDOW_IS_MAPPED (window) && (private->state & GDK_WINDOW_STATE_ICONIFIED)) { ShowWindow (GDK_WINDOW_HWND (window), SW_MINIMIZE); return; } /* If asked to just show an iconified window, do nothing. */ if (!deiconify && (private->state & GDK_WINDOW_STATE_ICONIFIED)) return; /* If asked to deiconify an already noniconified window, do * nothing. (Especially, don't cause the window to rise and * activate. There are different calls for that.) */ if (deiconify && !(private->state & GDK_WINDOW_STATE_ICONIFIED)) return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -