RukeとLuNaYuの日記
I know the truth.
I know whole.
And I...know you.
平凡な大学生活の日記です。時折まじめな長文を書く病気になります。興味がなければ読み飛ばしてください。
201706 << 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 >> 201708
スポンサーサイト (--/--/--(--) --:--:--)
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
アチューンズ (2006/06/03(土) 00:16:15)

_getch()が悪さをしていたのね。というか、コンソールからの入力待ちをしている間は、自分の所の関数を呼ぼうとしている他のプロセスは待機するようになっているみたい。

しかし、MDSNにこれらの関数は呼び出し元スレッドをロックするため、スレッド セーフになります。ロックされないバージョンについては、「_getch_nolock、_getwch_nolock」を参照してください。と書いてあるのでこの問題かと思って_getch_nolock()を使っても何も変わらなかった。とにかく、最終的にgeOShellのプラグインを作りたいのでコンソールI/Oがうまく使えない事自体は問題ではない。そこで(WIN32 APIのコンソール周りのAPIも少しいじってみたけれどやっぱりだめで)windowsプログラムにしてしまった。とりあえずiTunes側のプロトタイプはこれでOKかな。問題は、geOShellのプラグインってけっこうダーティーなプログラミングを要求されることだ。

//Windows versions
#define WINVER 0x0501
#define _WIN32_WINNT 0x0501
#define _WIN32_WINDOWS 0x0410
#define _WIN32_IE 0x0600

//ATL
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS
#include <atlbase.h>
#include <atlstr.h>
#include <atlcom.h>
CComModule _Module;

//other headers
#define WIN32_LEAN_AND_MEAN
#include <windows.h> 
#include <iostream>
#include <conio.h> 

// iTunes 
#undef GetFreeSpace
#import "c:\program files\itunes\itunes.exe" named_guids

/*CComInitializer : COM initializing class*/
class CComInitializer {
	bool initialized_;

public:
	CComInitializer() : initialized_(false) { }
	HRESULT init() {
		HRESULT hr;
		hr = ::CoInitialize(NULL);
		if ( initialized_ = SUCCEEDED(hr) )
			_Module.Init(NULL, ::GetModuleHandle(NULL));
		return hr;
	}

	~CComInitializer() {
		if ( initialized_ ) {
			_Module.Term();
			::CoUninitialize();
		}
	}
};

/*com_assert : error checking and throwing exeptions*/
void com_assert(HRESULT result, const std::string& msg) {
	if ( FAILED(result) )
		throw std::runtime_error(msg);
}

/* iTunesEvents : sink class*/
#define SINKID_iTunesEvents 0
class ATL_NO_VTABLE iTunesEvents :
	public CComObjectRootEx<CComSingleThreadModel>,
	public IDispEventImpl<SINKID_iTunesEvents, iTunesEvents, 
	&iTunesLib::DIID__IiTunesEvents,&iTunesLib::LIBID_iTunesLib, 1, 7>
{
public:
	iTunesEvents() {}
	BEGIN_COM_MAP(iTunesEvents)
		COM_INTERFACE_ENTRY_IID(iTunesLib::DIID__IiTunesEvents, iTunesEvents)
	END_COM_MAP()
	BEGIN_SINK_MAP(iTunesEvents)
		SINK_ENTRY_EX(SINKID_iTunesEvents, iTunesLib::DIID__IiTunesEvents,iTunesLib::ITEventDatabaseChanged,&handle_OnDatabaseChangedEvent)
		SINK_ENTRY_EX(SINKID_iTunesEvents, iTunesLib::DIID__IiTunesEvents,iTunesLib::ITEventPlayerPlay,&handle_OnPlayerPlayEvent)
		SINK_ENTRY_EX(SINKID_iTunesEvents, iTunesLib::DIID__IiTunesEvents,iTunesLib::ITEventPlayerStop,&handle_OnPlayerStopEvent)
		SINK_ENTRY_EX(SINKID_iTunesEvents, iTunesLib::DIID__IiTunesEvents,iTunesLib::ITEventPlayerPlayingTrackChanged,&handle_OnPlayerPlayingTrackChangedEvent)
		SINK_ENTRY_EX(SINKID_iTunesEvents, iTunesLib::DIID__IiTunesEvents,iTunesLib::ITEventUserInterfaceEnabled,&handle_OnUserInterfaceEnabledEvent)
		SINK_ENTRY_EX(SINKID_iTunesEvents, iTunesLib::DIID__IiTunesEvents,iTunesLib::ITEventCOMCallsDisabled,&handle_OnCOMCallsDisabledEvent)
		SINK_ENTRY_EX(SINKID_iTunesEvents, iTunesLib::DIID__IiTunesEvents,iTunesLib::ITEventCOMCallsEnabled,&handle_OnCOMCallsEnabledEvent)
		SINK_ENTRY_EX(SINKID_iTunesEvents, iTunesLib::DIID__IiTunesEvents,iTunesLib::ITEventQuitting,&handle_OnQuittingEvent)
		SINK_ENTRY_EX(SINKID_iTunesEvents, iTunesLib::DIID__IiTunesEvents,iTunesLib::ITEventAboutToPromptUserToQuit,&handle_OnAboutToPromptUserToQuitEvent)
		SINK_ENTRY_EX(SINKID_iTunesEvents, iTunesLib::DIID__IiTunesEvents,iTunesLib::ITEventSoundVolumeChanged,&handle_OnSoundVolumeChangedEvent)
	END_SINK_MAP()
	virtual void OnDatabaseChangedEvent(VARIANT deletedObjectIDs,VARIANT changedObjectIDs)=0;
	HRESULT _stdcall handle_OnDatabaseChangedEvent(VARIANT deletedObjectIDs,VARIANT changedObjectIDs){OnDatabaseChangedEvent(deletedObjectIDs,changedObjectIDs);return S_OK;}

	virtual void OnPlayerPlayEvent(VARIANT iTrack)=0;
	HRESULT _stdcall handle_OnPlayerPlayEvent(VARIANT iTrack){OnPlayerPlayEvent(iTrack);return S_OK;}

	virtual void OnPlayerStopEvent(VARIANT iTrack)=0;
	HRESULT _stdcall handle_OnPlayerStopEvent(VARIANT iTrack){OnPlayerStopEvent(iTrack);return S_OK;}

	virtual void OnPlayerPlayingTrackChangedEvent (VARIANT iTrack)=0;
	HRESULT _stdcall handle_OnPlayerPlayingTrackChangedEvent(VARIANT iTrack){OnPlayerPlayingTrackChangedEvent(iTrack);return S_OK;}

	virtual void OnUserInterfaceEnabledEvent ()=0;
	HRESULT _stdcall handle_OnUserInterfaceEnabledEvent(){OnUserInterfaceEnabledEvent();return S_OK;}

	virtual void OnCOMCallsDisabledEvent (iTunesLib::ITCOMDisabledReason reason)=0;
	HRESULT _stdcall handle_OnCOMCallsDisabledEvent (iTunesLib::ITCOMDisabledReason reason){OnCOMCallsDisabledEvent(reason);return S_OK;}

	virtual void OnCOMCallsEnabledEvent()=0;
	HRESULT _stdcall handle_OnCOMCallsEnabledEvent(){OnCOMCallsEnabledEvent();return S_OK;}

	virtual void OnQuittingEvent()=0;
	HRESULT _stdcall handle_OnQuittingEvent(){OnQuittingEvent();return S_OK;}

	virtual void OnAboutToPromptUserToQuitEvent()=0;
	HRESULT _stdcall handle_OnAboutToPromptUserToQuitEvent(){OnAboutToPromptUserToQuitEvent();return S_OK;}

	virtual void OnSoundVolumeChangedEvent(long newVolume)=0;
	HRESULT _stdcall handle_OnSoundVolumeChangedEvent(long newVolume){OnSoundVolumeChangedEvent(newVolume);return S_OK;}
};

#undef SINKID_iTunesEvents

/* ecom_event_sink : wrapper for sink*/
template<class Event>
class com_event_sink {
	typedef CComObject<Event> com_object_type;
	com_object_type*  sink_;
	CComPtr<IUnknown> unk_;
public:
	HRESULT create() {
		HRESULT hr = com_object_type::CreateInstance(&sink_);
		if ( SUCCEEDED(hr) ) 
			sink_->QueryInterface(IID_IUnknown,(void**)&unk_);
		return hr;
	}
	com_object_type* operator->() {
		return sink_;
	}
};

//Window
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
char szClassName[] = "iTunesTestAtlWithWindow";

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInst,
				   LPSTR lpszCmdLine, int nCmdShow)
{
	HWND hWnd;
	MSG msg;
	WNDCLASSEX myProg;
	if (!hPreInst) {
		myProg.cbSize=sizeof(WNDCLASSEX);
		myProg.style            =CS_HREDRAW | CS_VREDRAW;
		myProg.lpfnWndProc        =WndProc;
		myProg.cbClsExtra        =0;
		myProg.cbWndExtra        =0;
		myProg.hInstance        =hInstance;
		myProg.hIcon            =NULL;
		myProg.hCursor        =LoadCursor(NULL, IDC_ARROW);
		myProg.hbrBackground    =(HBRUSH)COLOR_BACKGROUND;
		myProg.lpszMenuName    =NULL;
		myProg.lpszClassName    =szClassName;
		myProg.hIconSm=NULL;
		if(!RegisterClassEx(&myProg)) return 0;
	}
	hWnd = CreateWindow(
		szClassName,
		"iTunesTest",
		WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		600,
		60,
		NULL,
		NULL,
		hInstance,
		NULL);
	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);
	while (GetMessage(&msg, NULL, 0, 0)) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return (int)msg.wParam;
}

/*global variables*/
CComInitializer com;
CComPtr<iTunesLib::IiTunes> iTunes=NULL;
class myiTunesEvents;
com_event_sink<myiTunesEvents> sink;

/*myiTunesEvents : actual event handler*/
class myiTunesEvents : public iTunesEvents {
	void OnDatabaseChangedEvent(VARIANT deletedObjectIDs,VARIANT changedObjectIDs){
		MessageBox(NULL,"DatabaseChanged is fired.","",MB_OK);

	};
	void OnPlayerPlayEvent(VARIANT iTrack) {
		MessageBox(NULL,"PlayerPlay is fired.","",MB_OK);
	}
	void OnPlayerStopEvent(VARIANT iTrack) {
		MessageBox(NULL,"PlayerStop is fired.","",MB_OK);
	}
	void OnPlayerPlayingTrackChangedEvent (VARIANT iTrack){
		MessageBox(NULL,"PlayerPlayingTrackChanged is fired.","",MB_OK);
	};	
	void OnUserInterfaceEnabledEvent(){
		MessageBox(NULL,"UserInterfaceEnabled is fired.","",MB_OK);
	};
	void OnCOMCallsDisabledEvent (iTunesLib::ITCOMDisabledReason reason){
		MessageBox(NULL,"ComCallsDisabled is fired.","",MB_OK);
	};
	void OnCOMCallsEnabledEvent(){
		MessageBox(NULL,"ComCallsEnabled is fired.","",MB_OK);
	};
	void OnQuittingEvent(){
		HRESULT hr;
		hr = sink->DispEventUnadvise(iTunes);
		com_assert(hr, "DispEventUnadvise failed");
		iTunes.Release();
		iTunes=NULL;
		MessageBox(NULL,"Quitting is fired.","",MB_OK);
	};
	void OnAboutToPromptUserToQuitEvent(){
		HRESULT hr;
		hr = sink->DispEventUnadvise(iTunes);
		com_assert(hr, "DispEventUnadvise failed");
		iTunes.Release();
		iTunes=NULL;
		//MessageBox(NULL,"AboutToPromptUserToQuit is fired.","",MB_OK);
	};
	void OnSoundVolumeChangedEvent(long newVolume){
		MessageBox(NULL,"SoundVolumeChanged is fired.","",MB_OK);
	};
};

//CALLBACK Procedure
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	HRESULT hr;
	switch (msg) {
case WM_DESTROY:
	//releasing
	if(iTunes!=NULL){
		hr = sink->DispEventUnadvise(iTunes);
		com_assert(hr, "DispEventUnadvise failed");
		iTunes.Release();
		iTunes=NULL;
	}
	//quitting
	PostQuitMessage(0);
	break;
case WM_CREATE:
	//initializing COM
	hr = com.init();
	com_assert(hr, "CoInitialize failed");
	//creating iTunes object
	hr = iTunes.CoCreateInstance(iTunesLib::CLSID_iTunesApp);
	com_assert(hr, "Creation of iTunesAppClass failed");
	//creating my event handler
	hr = sink.create();
	com_assert(hr,"CCI Event sink failed");
	//connecting my event handler to iTunes
	hr = sink->DispEventAdvise(iTunes);
	com_assert(hr, "DispEventAdvise failed");
	break;
case WM_KEYUP:
	if(wParam=='X'){
		if(iTunes!=NULL)iTunes->Quit();
	}else if(wParam=='Q'){
		DestroyWindow(hWnd);
	}else if(wParam==VK_SPACE){
		if(iTunes==NULL){
			hr = iTunes.CoCreateInstance(iTunesLib::CLSID_iTunesApp);
			com_assert(hr, "Creation of iTunesAppClass failed");
			hr = sink->DispEventAdvise(iTunes);
			com_assert(hr, "DispEventAdvise failed");
		}
		iTunes->PlayPause();
	}else if(wParam=='B'){
		if(iTunes!=NULL)iTunes->BackTrack();
	}else if(wParam=='N'){
		if(iTunes!=NULL)iTunes->NextTrack();
	}else if(wParam=='M'){
		if(iTunes!=NULL){
			if(iTunes->BrowserWindow->Minimized==VARIANT_TRUE){
				iTunes->BrowserWindow->Minimized=VARIANT_FALSE;
			}else{
				iTunes->BrowserWindow->Minimized=VARIANT_TRUE;
			}
		}
	}
	break;
default:
	return(DefWindowProc(hWnd, msg, wParam, lParam));
	}
	return (0L);
}
スポンサーサイト
コメント
この記事へのコメント
コメントを投稿する

管理者にだけ表示を許可する
トラックバック
この記事のトラックバックURL
この記事へのトラックバック
(C)Copyright 2003-2007 by Ruke All rights reserved. Powered By FC2. VALID HTML? VALID CSS?
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。