示例#1
0
void MCStack::realize()
{
	if (MCnoui)
	{
		start_externals();
		return;
	}

	if (MCModeMakeLocalWindows())
	{
		uint32_t wstyle, exstyle;
		loadwindowshape();
		getstyle(wstyle, exstyle);
		RECT wrect ;

		// IM-2013-09-23: [[ FullscreenMode ]] Don't change stack rect if fullscreen
		/* CODE DELETED */

		wrect = getwrect(rect, wstyle, exstyle);
		LONG x = wrect.left;
		LONG y = wrect.top;
		LONG width = wrect.right - wrect.left;
		LONG height = wrect.bottom - wrect.top;
		if (flags & F_WM_PLACE && !(state & CS_BEEN_MOVED))
			x = CW_USEDEFAULT;
		window = new _Drawable;
		window->type = DC_WINDOW;
		window->handle.window = 0; // protect against creation callbacks

		// MW-2011-02-15: [[ Bug 9396 ]] Tooltips should have a shadow on Windows.
		Boolean isxpmenu = (mode == WM_PULLDOWN || mode == WM_POPUP || mode == WM_CASCADE || mode == WM_TOOLTIP) \
		                   && (MCcurtheme && MCcurtheme->getthemeid() == LF_NATIVEWIN);

		// MW-2012-09-07: [[ Bug 10368 ]] If the 'no-shadow' bit is set, then we don't
		//   want to use the menu class.
		if (getflag(F_DECORATIONS) && (decorations & WD_NOSHADOW) != 0)
			isxpmenu = False;

		HWND t_parenthwnd = NULL;

		// MW-2007-07-06: [[ Bug 3226 ]] If the platform is NT always create a Unicode window
		if ((MCruntimebehaviour & RTB_NO_UNICODE_WINDOWS) == 0 && !isxpmenu && mode < WM_PULLDOWN)
			window -> handle . window = (MCSysWindowHandle)CreateWindowExW(exstyle, MC_WIN_CLASS_NAME_W, WideCString(getname_cstring()),wstyle | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, x, y, width, height,
		                 t_parenthwnd, NULL, MChInst, NULL);
		else
			window->handle.window = (MCSysWindowHandle)CreateWindowExA(exstyle, isxpmenu? MC_MENU_WIN_CLASS_NAME: mode >= WM_PULLDOWN ? MC_POPUP_WIN_CLASS_NAME
		                 : MC_WIN_CLASS_NAME, getname_cstring(), wstyle | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, x, y, width, height,
		                 t_parenthwnd, NULL, MChInst, NULL);

		SetWindowLongA((HWND)window->handle.window, GWL_USERDATA, mode);
		
		if (flags & F_DECORATIONS && !(decorations & WD_SHAPE) && !(decorations & WD_CLOSE))
			EnableMenuItem(GetSystemMenu((HWND)window->handle.window, False), SC_CLOSE, MF_BYCOMMAND | MF_GRAYED);

		if (m_window_shape != nil && m_window_shape -> is_sharp)
		{
			MCRegionRef t_region;
			t_region = (MCRegionRef)m_window_shape -> handle;
			MCRegionOffset(t_region, rect . x - wrect . left, rect . y - wrect . top);
			MCRegionSetAsWindowShape(t_region, window->handle.window);

			// The window now owns the region.
			m_window_shape -> handle = nil;
		}

		if ((m_window_shape == NULL || m_window_shape -> is_sharp) && blendlevel != 100)
			setopacity(blendlevel * 255 / 100);
	}
	
	start_externals();
}
示例#2
0
static int MCA_do_file_dialog(MCExecPoint& ep, const char *p_title, const char *p_prompt, const char *p_filter, const char *p_initial, unsigned int p_options)
{
	int t_result = 0;

	char *t_initial_file;
	t_initial_file = NULL;

	char *t_initial_folder;
	t_initial_folder = NULL;

	ep . clear();

	if (*p_initial != '\0')
	{
		char *t_initial_clone;
		t_initial_clone = strdup(p_initial);
		MCU_w32path2std(t_initial_clone);
		MCU_fix_path(t_initial_clone);

		if (MCS_exists(t_initial_clone, False))
			t_initial_folder = t_initial_clone;
		else if ((p_options & MCA_OPTION_SAVE_DIALOG) != 0)
		{
			t_initial_file = strrchr(t_initial_clone, '/');
			if (t_initial_file == NULL)
			{
				if (strlen(t_initial_clone) != 0)
					t_initial_file = t_initial_clone;
			}
			else
			{
				*t_initial_file = '\0';
				t_initial_file++;
				
				if (t_initial_file[0] == '\0')
					t_initial_file = NULL;

				if (MCS_exists(t_initial_clone, False))
					t_initial_folder = t_initial_clone;
			}
		}
		else
		{
			char *t_leaf;
			t_leaf = strrchr(t_initial_clone, '/');
			if (t_leaf != NULL)
			{
				*t_leaf = '\0';
				if (MCS_exists(t_initial_clone, False))
					t_initial_folder = t_initial_clone;
			}
		}

		t_initial_file = strdup(t_initial_file);
		t_initial_folder = MCS_resolvepath(t_initial_folder);

		delete t_initial_clone;
	}

	if (!MCModeMakeLocalWindows())
	{
		char ** t_filters = NULL;
		uint32_t t_filter_count = 0;

		if (p_filter != NULL)
		{
			const char *t_strptr = p_filter;
			while (t_strptr[0] != '\0')
			{
				t_filter_count++;
				t_filters = (char**)realloc(t_filters, t_filter_count * sizeof(char*));
				t_filters[t_filter_count - 1] = (char *)t_strptr;
				t_strptr += strlen(t_strptr) + 1;
			}
		}

		MCRemoteFileDialog(ep, p_title, p_prompt, t_filters, t_filter_count, t_initial_folder, t_initial_file, (p_options & MCA_OPTION_SAVE_DIALOG) != 0, (p_options & MCA_OPTION_PLURAL) != 0);

		free(t_filters);
		return 0;
	}

	Window t_window;
	t_window = MCModeGetParentWindow();

	bool t_succeeded;
	int t_filter_index;

	if (MCmajorosversion >= 0x0600)
	{
		static SHCreateItemFromParsingNamePtr  s_shcreateitemfromparsingname = NULL;
		if (s_shcreateitemfromparsingname == NULL)
		{
			static HMODULE s_shell32_module = NULL;
			s_shell32_module = LoadLibraryA("shell32.dll");
			s_shcreateitemfromparsingname = (SHCreateItemFromParsingNamePtr)GetProcAddress(s_shell32_module, "SHCreateItemFromParsingName");
		}

		IFileSaveDialog *t_file_save_dialog;
		IFileOpenDialog *t_file_open_dialog;
		IFileDialog *t_file_dialog;

		t_file_dialog = NULL;

		HRESULT t_hresult;

		if ((p_options & MCA_OPTION_SAVE_DIALOG) == 0)
		{
			t_hresult = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, __uuidof(IFileOpenDialog), (LPVOID *)&t_file_open_dialog);
			t_succeeded = SUCCEEDED(t_hresult);

			t_file_dialog = t_file_open_dialog;
		}
		else
		{
			t_hresult = CoCreateInstance(CLSID_FileSaveDialog, NULL, CLSCTX_INPROC_SERVER, __uuidof(IFileSaveDialog), (LPVOID *)&t_file_save_dialog);
			t_succeeded = SUCCEEDED(t_hresult);

			t_file_dialog = t_file_save_dialog;
		}

		if (t_succeeded)
		{
			DWORD t_options;

			t_options = FOS_FORCEFILESYSTEM | FOS_NOCHANGEDIR | FOS_PATHMUSTEXIST;
			if (p_options & MCA_OPTION_PLURAL)
				t_options |= FOS_ALLOWMULTISELECT;
			if (p_options & MCA_OPTION_SAVE_DIALOG)
				t_options |= FOS_OVERWRITEPROMPT;
			if (p_options & MCA_OPTION_FOLDER_DIALOG)
				t_options |= FOS_PICKFOLDERS;
			else
				t_options |= FOS_FILEMUSTEXIST;

			t_hresult = t_file_dialog -> SetOptions(t_options);
			t_succeeded = SUCCEEDED(t_hresult);
		}

		if (t_succeeded && t_initial_folder != NULL)
		{
			IShellItem *t_initial_folder_shellitem;
			t_initial_folder_shellitem = NULL;
			t_hresult = s_shcreateitemfromparsingname(WideCString(t_initial_folder), NULL, __uuidof(IShellItem), (LPVOID *)&t_initial_folder_shellitem);
			if (SUCCEEDED(t_hresult))
				t_file_dialog -> SetFolder(t_initial_folder_shellitem);
			if (t_initial_folder_shellitem != NULL)
				t_initial_folder_shellitem -> Release();
			t_succeeded = SUCCEEDED(t_hresult);
		}

		if (t_succeeded && t_initial_file != NULL)
		{
			t_hresult = t_file_dialog -> SetFileName(WideCString(t_initial_file));
			t_succeeded = SUCCEEDED(t_hresult);
		}

		if (t_succeeded && p_filter != NULL && (p_options & MCA_OPTION_FOLDER_DIALOG) == 0)
		{
			uint4 t_filter_length, t_filter_count;
			measure_filter(p_filter, t_filter_length, t_filter_count);

			WideCString t_filters(p_filter, t_filter_length);
			COMDLG_FILTERSPEC *t_filter_spec;

			filter_to_spec(t_filters, t_filter_count, t_filter_spec);

			t_hresult = t_file_dialog -> SetFileTypes(t_filter_count, t_filter_spec);
			t_succeeded = SUCCEEDED(t_hresult);

			delete t_filter_spec;
		}

		if (t_succeeded && p_filter != NULL && (p_options & MCA_OPTION_FOLDER_DIALOG) == 0)
		{
			t_hresult = t_file_dialog -> SetFileTypeIndex(1);
			t_succeeded = SUCCEEDED(t_hresult);
		}

		if (t_succeeded)
			t_hresult = t_file_dialog -> SetTitle(WideCString(p_prompt));

		if (t_succeeded)
		{
			t_hresult = t_file_dialog -> Show(t_window != NULL ? (HWND)t_window -> handle . window : NULL);
			t_succeeded = SUCCEEDED(t_hresult);
		}

		if ((p_options & MCA_OPTION_SAVE_DIALOG) == 0)
		{
			IShellItemArray *t_file_items;
			t_file_items = NULL;
			if (t_succeeded)
			{
				t_hresult = t_file_open_dialog -> GetResults(&t_file_items);
				t_succeeded = SUCCEEDED(t_hresult);
			}

			DWORD t_file_item_count;
			if (t_succeeded)
			{
				t_hresult = t_file_items -> GetCount(&t_file_item_count);
				t_succeeded = SUCCEEDED(t_hresult);
			}

			if (t_succeeded)
			{
				ep . clear();
				for(uint4 t_index = 0; t_index < t_file_item_count && t_succeeded; ++t_index)
				{
					IShellItem *t_file_item;
					t_file_item = NULL;
					if (t_succeeded)
					{
						t_hresult = t_file_items -> GetItemAt(t_index, &t_file_item);
						t_succeeded = SUCCEEDED(t_hresult);
					}

					if (t_succeeded)
					{
						t_hresult = append_shellitem_path_and_release(ep, t_file_item, t_index == 0);
						t_succeeded = SUCCEEDED(t_hresult);
					}
				}
			}

			if (t_file_items != NULL)
				t_file_items -> Release();
		}
		else
		{
			IShellItem *t_file_item;
			t_file_item = NULL;
			if (t_succeeded)
			{
				t_hresult = t_file_dialog -> GetResult(&t_file_item);
				t_succeeded = SUCCEEDED(t_hresult);
			}

			if (t_succeeded)
			{
				ep . clear();
				t_hresult = append_shellitem_path_and_release(ep, t_file_item, true);
				t_succeeded = SUCCEEDED(t_hresult);
			}
		}

		t_filter_index = 0;
		if (t_succeeded && (p_options & MCA_OPTION_FOLDER_DIALOG) == 0)
		{
			UINT t_index;
			t_hresult = t_file_dialog -> GetFileTypeIndex(&t_index);
			t_succeeded = SUCCEEDED(t_hresult);
			if (t_succeeded)
				t_filter_index = (int)t_index;
		}

		if (t_file_dialog != NULL)
			t_file_dialog -> Release();

		if (!t_succeeded)
			t_result = t_hresult;
		else
			t_result = 0;
	}
	else
	{
		OPENFILENAMEA t_open_dialog;
		memset(&t_open_dialog, 0, sizeof(OPENFILENAMEA));
		t_open_dialog . lStructSize = sizeof(OPENFILENAMEA);

		char *t_initial_file_buffer = new char[MAX_PATH];
		if (t_initial_file != NULL)
			strcpy(t_initial_file_buffer, t_initial_file);
		else
			*t_initial_file_buffer = '\0';

		t_open_dialog . lpstrFilter = p_filter;
		t_open_dialog . nFilterIndex = 1;
		t_open_dialog . lpstrFile = t_initial_file_buffer;
		t_open_dialog . nMaxFile = MAX_PATH;
		t_open_dialog . lpstrInitialDir = t_initial_folder;
		t_open_dialog . lpstrTitle = p_prompt;
		t_open_dialog . Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_NOCHANGEDIR |
														OFN_LONGNAMES | OFN_PATHMUSTEXIST | OFN_EXPLORER |
														OFN_ENABLEHOOK | OFN_ENABLESIZING;

		if (p_options & MCA_OPTION_PLURAL)
			t_open_dialog . Flags |= OFN_ALLOWMULTISELECT;

		if (p_options & MCA_OPTION_SAVE_DIALOG)
			t_open_dialog . Flags |= OFN_OVERWRITEPROMPT;

		t_open_dialog . lpstrFilter = p_filter;
		t_open_dialog . lpfnHook = open_dialog_hook;
		t_open_dialog . hwndOwner = t_window != NULL ? (HWND)t_window -> handle . window : NULL;

		if (p_options & MCA_OPTION_SAVE_DIALOG)
			t_succeeded = GetSaveFileNameA((LPOPENFILENAMEA)&t_open_dialog) == TRUE;
		else
		{
			*t_open_dialog . lpstrFile = '\0';
			t_succeeded = GetOpenFileNameA((LPOPENFILENAMEA)&t_open_dialog) == TRUE;
		}

		if (!t_succeeded)
			t_result = CommDlgExtendedError();

		// MW-2005-07-26: Try again without the specified filename if it was invalid
		if (t_result == FNERR_INVALIDFILENAME)
		{
			*t_open_dialog . lpstrFile = '\0';
			if (p_options & MCA_OPTION_SAVE_DIALOG)
				t_succeeded = GetSaveFileNameA((LPOPENFILENAMEA)&t_open_dialog) == TRUE;
			else
				t_succeeded = GetOpenFileNameA((LPOPENFILENAMEA)&t_open_dialog) == TRUE;

			if (!t_succeeded)
				t_result = CommDlgExtendedError();	
		}

		if (t_result == FNERR_BUFFERTOOSMALL)
			t_succeeded = true;

		if (t_succeeded)
		{
			build_paths(ep);
			t_filter_index = t_open_dialog . nFilterIndex;
		}

		delete t_initial_file_buffer;
	}

	if (t_succeeded)
	{
		if (p_options & MCA_OPTION_RETURN_FILTER)
		{
			const char *t_type = p_filter;
			const char *t_types = p_filter;
			for(int t_index = t_filter_index * 2 - 1; t_index > 1; t_types += 1)
				if (*t_types == '\0')
					t_type = t_types + 1, t_index -= 1;
			MCresult -> copysvalue(t_type);
		}

		t_result = 0;
	}

	waitonbutton();

	if (t_initial_folder != NULL)
		delete t_initial_folder;

	if (t_initial_file != NULL)
		delete t_initial_file;

	return t_result;
}
示例#3
0
// MW-2006-03-20: Bug 3316 - There seems absolutely no way of preventing flicker
//   when transitioning from no alpha to alpha. Therefore, we need to create a new
//   window opened *behind* the current window; show it; redraw it; then delete
//   the existing window.
void MCStack::setopacity(uint1 p_level)
{
	// If the stack is not ours to open, then we do nothing ('runtime' mode/remoteable
	// window).
	if (!MCModeMakeLocalWindows())
		return;

	// Do nothing if not NT
	if (MCmajorosversion < 0x0500)
		return;

	if (m_window_shape != NULL && !m_window_shape -> is_sharp)
		composite();
	else if (window != NULL)
	{
		HWND t_old_window;
		t_old_window = NULL;

		DWORD t_old_long, t_new_long;
		t_old_long = GetWindowLong((HWND)window -> handle . window, GWL_EXSTYLE);

		if (p_level == 255)
			t_new_long = t_old_long & ~WS_EX_LAYERED;
		else
			t_new_long = t_old_long | WS_EX_LAYERED;

		if (t_new_long != t_old_long)
		{
			if (IsWindowVisible((HWND)window -> handle . window) && (t_new_long & WS_EX_LAYERED) != 0)
				t_old_window = (HWND)window -> handle . window;
			else
				SetWindowLong((HWND)window -> handle . window, GWL_EXSTYLE, t_new_long);
		}

		if (t_old_window != NULL)
		{
			uint32_t t_style, t_ex_style;
			getstyle(t_style, t_ex_style);

			// MW-2006-07-27: [[ Bug 3690 ]] - Make sure layered attribute is set if we need it
			t_ex_style = (t_ex_style & ~WS_EX_LAYERED) | (t_new_long & WS_EX_LAYERED);

			RECT t_rect;
			t_rect = getwrect(rect, t_style, t_ex_style);

			Bool t_is_xp_menu;
			t_is_xp_menu = (mode == WM_PULLDOWN || mode == WM_POPUP || mode == WM_CASCADE) && (MCcurtheme && MCcurtheme->getthemeid() == LF_NATIVEWIN);

			if (!t_is_xp_menu && mode < WM_PULLDOWN)
				window -> handle . window = (MCSysWindowHandle)CreateWindowExW(t_ex_style, MC_WIN_CLASS_NAME_W, WideCString(getname_cstring()), t_style | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, t_rect . left, t_rect . top, t_rect . right - t_rect . left, t_rect . bottom - t_rect . top, NULL, NULL, MChInst, NULL);
			else
				window -> handle . window = (MCSysWindowHandle)CreateWindowExA(t_ex_style, t_is_xp_menu ? MC_MENU_WIN_CLASS_NAME : mode >= WM_PULLDOWN ? MC_POPUP_WIN_CLASS_NAME : MC_WIN_CLASS_NAME, getname_cstring(), t_style | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, t_rect . left, t_rect . top, t_rect . right - t_rect . left, t_rect . bottom - t_rect . top, NULL, NULL, MChInst, NULL);
			
			// MW-2010-10-22: [[ Bug 8151 ]] Make sure we update the title string.
			if (titlestring != nil)
				MCscreen -> setname(window, titlestring);

			SetWindowLongA((HWND)window->handle.window, GWL_USERDATA, mode);
			
			if (flags & F_DECORATIONS && !(decorations & WD_SHAPE) && !(decorations & WD_CLOSE))
				EnableMenuItem(GetSystemMenu((HWND)window->handle.window, False), SC_CLOSE, MF_BYCOMMAND | MF_GRAYED);
		
			if (m_window_shape != nil && m_window_shape -> is_sharp)
			{
				MCRegionRef t_region;
				t_region = (MCRegionRef)m_window_shape -> handle;
				MCRegionOffset(t_region, rect . x - t_rect . left, rect . y - t_rect . top);
				MCRegionSetAsWindowShape(t_region, window->handle.window);

				// The window now owns the region.
				m_window_shape -> handle = nil;
			}

			RevokeDragDrop(t_old_window);
			CoLockObjectExternal(droptarget, FALSE, TRUE);
			droptarget -> setstack(NULL);

			droptarget -> setstack(this);
			CoLockObjectExternal(droptarget, TRUE, TRUE);
			RegisterDragDrop((HWND)window -> handle . window, droptarget);

			SetWindowPos((HWND)window -> handle . window, t_old_window, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOREDRAW | SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_SHOWWINDOW);

			MCPlayer *t_player;
			for(t_player = MCplayers; t_player != NULL; t_player = t_player -> getnextplayer())
				if (t_player -> getstack() == this)
					t_player -> changewindow((MCSysWindowHandle)t_old_window);
		}

		if (p_level < 255)
			SetLayeredWindowAttributes((HWND)window -> handle . window, 0, p_level, LWA_ALPHA);

		if (t_old_window != NULL)
		{
			RedrawWindow((HWND)window -> handle . window, NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_UPDATENOW);
			DestroyWindow(t_old_window);
		}
	}
}