This source file includes following definitions.
- callback
- OnOpenWithDialogDone
- OpenWithDialogTask
- OpenWithDialogAsync
#include "win8/test/open_with_dialog_async.h"
#include <shlobj.h>
#include "base/bind.h"
#include "base/callback.h"
#include "base/location.h"
#include "base/memory/ref_counted.h"
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.h"
#include "base/threading/platform_thread.h"
#include "base/threading/thread.h"
#include "base/win/windows_version.h"
namespace win8 {
namespace {
struct OpenWithContext {
OpenWithContext(
HWND parent_window_in,
const base::string16& file_name_in,
const base::string16& file_type_class_in,
int open_as_info_flags_in,
const scoped_refptr<base::SingleThreadTaskRunner>& client_runner_in,
const OpenWithDialogCallback& callback_in);
~OpenWithContext();
base::Thread thread;
HWND parent_window;
base::string16 file_name;
base::string16 file_type_class;
int open_as_info_flags;
scoped_refptr<base::SingleThreadTaskRunner> client_runner;
OpenWithDialogCallback callback;
};
OpenWithContext::OpenWithContext(
HWND parent_window_in,
const base::string16& file_name_in,
const base::string16& file_type_class_in,
int open_as_info_flags_in,
const scoped_refptr<base::SingleThreadTaskRunner>& client_runner_in,
const OpenWithDialogCallback& callback_in)
: thread("OpenWithDialog"),
parent_window(parent_window_in),
file_name(file_name_in),
file_type_class(file_type_class_in),
open_as_info_flags(open_as_info_flags_in),
client_runner(client_runner_in),
callback(callback_in) {
thread.init_com_with_mta(false);
thread.Start();
}
OpenWithContext::~OpenWithContext() {}
void OnOpenWithDialogDone(OpenWithContext* context, HRESULT result) {
DCHECK(context->client_runner->BelongsToCurrentThread());
OpenWithDialogCallback callback(context->callback);
delete context;
callback.Run(result);
}
void OpenWithDialogTask(OpenWithContext* context) {
DCHECK_EQ(context->thread.thread_id(), base::PlatformThread::CurrentId());
OPENASINFO open_as_info = {
context->file_name.c_str(),
context->file_type_class.c_str(),
context->open_as_info_flags
};
HRESULT result = ::SHOpenWithDialog(context->parent_window, &open_as_info);
if (!context->client_runner->PostTask(
FROM_HERE,
base::Bind(&OnOpenWithDialogDone, context, result))) {
DLOG(ERROR) << "leaking OpenWith thread; result = " << std::hex << result;
}
}
}
void OpenWithDialogAsync(
HWND parent_window,
const base::string16& file_name,
const base::string16& file_type_class,
int open_as_info_flags,
const OpenWithDialogCallback& callback) {
DCHECK_GE(base::win::GetVersion(), base::win::VERSION_VISTA);
OpenWithContext* context =
new OpenWithContext(parent_window, file_name, file_type_class,
open_as_info_flags,
base::ThreadTaskRunnerHandle::Get(), callback);
context->thread.message_loop()->PostTask(
FROM_HERE,
base::Bind(&OpenWithDialogTask, context));
}
}