LRESULT CALLBACK
Cieambulant::PluginWinProc(UINT msg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) {
	typedef HRGN NPRegion;
	if (updatePlayer() != S_OK)
		return S_FALSE;

	switch (msg) {
	case WM_PAINT:
		{
			PAINTSTRUCT ps;
			HDC hdc = BeginPaint(&ps);
			if (m_hwnd && m_ambulant_player) {
				HDC hdc = ::GetDC(m_hwnd);
				m_ambulant_player->redraw(m_hwnd, hdc, NULL); // XXX Should pass dirty rect
				::ShowWindow(m_hwnd, SW_SHOW);
				::ReleaseDC(m_hwnd, hdc);
			}
			EndPaint(&ps);
		}
		break;
	case WM_LBUTTONDOWN:
	case WM_MOUSEMOVE:
		POINT point;
		point.x=GET_X_LPARAM(lParam);
		point.y=GET_Y_LPARAM(lParam);
		if (m_ambulant_player) {
			if (msg == WM_MOUSEMOVE) {
				// code copied from MmView.cpp
				int new_cursor_id = m_ambulant_player->get_cursor(point.x, point.y, m_hwnd);
				if(new_cursor_id != m_cursor_id) {
					HINSTANCE hIns = 0;
					HCURSOR new_cursor = 0;
					if(new_cursor_id == 0) {
						new_cursor = LoadCursor(hIns, IDC_ARROW);
					} else {
						new_cursor = LoadCursor(hIns, IDC_HAND);
					}
					SetClassLongPtr(m_hwnd, GCLP_HCURSOR, HandleToLong(new_cursor));
					m_cursor_id = new_cursor_id;
				}
			} else {
				m_ambulant_player->on_click(point.x, point.y, m_hwnd);
			}
		}
		break;

	default:
		break;
	}
	BOOL rv = DefWindowProc(msg, wParam, lParam);
	bHandled = rv;
	return rv;
}
예제 #2
0
/*
 * @implemented
 */
HFILE
WINAPI
_lcreat(LPCSTR lpPathName, int iAttribute)
{
    HANDLE hFile;

    iAttribute &= FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
    hFile = CreateFileA(lpPathName,
                        GENERIC_READ | GENERIC_WRITE,
                        (FILE_SHARE_READ | FILE_SHARE_WRITE),
                        NULL,
                        CREATE_ALWAYS,
                        iAttribute,
                        NULL);

    return HandleToLong(hFile);
}
예제 #3
0
//
// Set texture info to a sender shared memory map without affecting the 
// interop class globals used for GL/DX interop texture sharing
// TODO - use pointer from initial map creation
bool spoutSenderNames::SetSenderInfo(const char* sendername, unsigned int width, unsigned int height, HANDLE dxShareHandle, DWORD dwFormat) 
{
	SharedTextureInfo info;

	std::string nameString = sendername;
	
	auto foundSender = m_senders->find(nameString);

	if (foundSender == m_senders->end())
	{
		return false;
	}

	auto senderInfoMap = foundSender->second;

	char *pBuf = senderInfoMap->Lock();

	if (!pBuf)
	{
		return false;
	}
	
	info.width       = (unsigned __int32)width;
	info.height      = (unsigned __int32)height;
#ifdef _M_X64
	info.shareHandle = (unsigned __int32)(HandleToLong(dxShareHandle));
#else
	info.shareHandle = (unsigned __int32)dxShareHandle;
#endif
	// info.shareHandle = (unsigned __int32)dxShareHandle; 
	info.format      = (unsigned __int32)dwFormat;
	// Usage not used

	memcpy((void *)pBuf, (void *)&info, sizeof(SharedTextureInfo) );

	senderInfoMap->Unlock();
	
	return true;

} // end SetSenderInfo
예제 #4
0
static void SendWordToServer()
{
DWORD_PTR SendMsgAnswer;
DWORD flags;
LRESULT lr;

	if( !IsWindow( GlobalData->ServerWND ) )
		return;

	// Ask for needing to retrieve word - WPARAM = 1
	lr = SendMessageTimeout(GlobalData->ServerWND, WM_MY_SHOW_TRANSLATION, 1, 0, SMTO_ABORTIFHUNG, MOUSEOVER_INTERVAL, &SendMsgAnswer);
	if( lr == 0 || SendMsgAnswer == 0)	//No answer or no needing
		return;

	flags = SendMsgAnswer;

	if (hGetWordLib == 0 && ( flags & GD_FLAG_METHOD_STANDARD ) ) {
		hGetWordLib = LoadLibraryW(GlobalData->LibName);
		if (hGetWordLib) {
			GetWordProc = (GetWordProc_t)GetProcAddress(hGetWordLib, "__gdGetWord");
		}
		else {
			hGetWordLib = INVALID_HANDLE_VALUE;
		}
	}

	GlobalData->CurMod.MatchedWord[0] = 0;
	GlobalData->CurMod.WordLen = 0;
	GlobalData->CurMod.BeginPos = 0;

	if( ( flags & GD_FLAG_METHOD_GD_MESSAGE ) != 0 && uGdAskMessage != 0 ) {
		int n;
		gds.dwSize = sizeof(gds);
		gds.cwData = Buffer;
		gds.dwMaxLength = sizeof(Buffer) / sizeof(Buffer[0]);
		Buffer[0] = 0;
		gds.hWnd = GlobalData->LastWND;
		gds.Pt = GlobalData->LastPt;
		lr = SendMessageTimeout(gds.hWnd, uGdAskMessage, 0, (LPARAM)&gds, SMTO_ABORTIFHUNG, REQUEST_MESSAGE_INTERVAL, &SendMsgAnswer);
		if(lr != 0 && SendMsgAnswer != 0) {
			n = WideCharToMultiByte(CP_UTF8, 0, gds.cwData, lstrlenW(gds.cwData), GlobalData->CurMod.MatchedWord, sizeof(GlobalData->CurMod.MatchedWord) - 1, 0, 0);
			GlobalData->CurMod.MatchedWord[n] = 0;
			GlobalData->CurMod.WordLen = n;
			GlobalData->CurMod.BeginPos = 0;
			if(n > 0) {
				if( IsWindow( GlobalData->ServerWND ) ) {
#ifdef __WIN64
					GlobalData32->LastWND = HandleToLong( GlobalData->LastWND );
					GlobalData32->CurMod.WordLen = n;
					GlobalData32->CurMod.BeginPos = 0;
					lstrcpyn( GlobalData32->CurMod.MatchedWord, GlobalData->CurMod.MatchedWord, sizeof( GlobalData32->CurMod.MatchedWord ) );
#endif
					SendMessageTimeout(GlobalData->ServerWND, WM_MY_SHOW_TRANSLATION, 0, 1, SMTO_ABORTIFHUNG, MOUSEOVER_INTERVAL, &SendMsgAnswer);
				}
			}
			return;
		}
	}

	if( ( flags & GD_FLAG_METHOD_STANDARD ) != 0 && GetWordProc != 0 ) {
		GlobalData->CurMod.WND = GlobalData->LastWND;
		GlobalData->CurMod.Pt = GlobalData->LastPt;

		LPARAM lparam = GetWordProc(&(GlobalData->CurMod));
		// lparam == 0 - need to reverse RTL text, else don't reverse

		if (GlobalData->CurMod.WordLen > 0) {
			if( IsWindow( GlobalData->ServerWND ) ) {
#ifdef __WIN64
				GlobalData32->LastWND = HandleToLong( GlobalData->LastWND );
				GlobalData32->CurMod.WordLen = GlobalData->CurMod.WordLen;
				GlobalData32->CurMod.BeginPos = GlobalData->CurMod.BeginPos;
				lstrcpyn( GlobalData32->CurMod.MatchedWord, GlobalData->CurMod.MatchedWord, sizeof( GlobalData32->CurMod.MatchedWord ) );
#endif
				SendMessageTimeout(GlobalData->ServerWND, WM_MY_SHOW_TRANSLATION, 0, lparam, SMTO_ABORTIFHUNG, MOUSEOVER_INTERVAL, &SendMsgAnswer);
			}
			return;
		}
	}

	if( ( flags & GD_FLAG_METHOD_IACCESSIBLEEX ) != 0 ) {
		getWordByAccEx( GlobalData->LastPt );
		if (GlobalData->CurMod.WordLen > 0 ) {
			if( IsWindow( GlobalData->ServerWND ) ) {
#ifdef __WIN64
				GlobalData32->LastWND = HandleToLong( GlobalData->LastWND );
				GlobalData32->CurMod.WordLen = GlobalData->CurMod.WordLen;
				GlobalData32->CurMod.BeginPos = GlobalData->CurMod.BeginPos;
				lstrcpyn( GlobalData32->CurMod.MatchedWord, GlobalData->CurMod.MatchedWord, sizeof( GlobalData32->CurMod.MatchedWord ) );
#endif
				SendMessageTimeout(GlobalData->ServerWND, WM_MY_SHOW_TRANSLATION, 0, 1, SMTO_ABORTIFHUNG, MOUSEOVER_INTERVAL, &SendMsgAnswer);
			}
			return;
		}
	}

	if( ( flags & GD_FLAG_METHOD_UI_AUTOMATION ) != 0 && IsWindow( GlobalData->ServerWND ) ) {
#ifdef __WIN64
		GlobalData32->CurMod.MatchedWord[0] = 0;
		GlobalData32->CurMod.WordLen = 0;
		GlobalData32->CurMod.BeginPos = 0;
		GlobalData32->LastPt = GlobalData->LastPt;
#endif
		PostMessage( GlobalData->ServerWND, WM_MY_SHOW_TRANSLATION, 0, 1 );
	}		
}
예제 #5
0
파일: txthost.c 프로젝트: RareHare/reactos
DECLSPEC_HIDDEN HRESULT WINAPI ITextHostImpl_TxActivate(ITextHost *iface, LONG *plOldState)
{
    ITextHostImpl *This = impl_from_ITextHost(iface);
    *plOldState = HandleToLong(SetActiveWindow(This->hWnd));
    return (*plOldState ? S_OK : E_FAIL);
}
예제 #6
0
파일: os_win_gl.c 프로젝트: skyview059/vu
// gs_context creates an opengl context. Actually it creates two of them.
// The first context is used to find better functions to create the final
// context. Note that the pixel format is done only once for a window so
// it must be correctly chosen.
long gs_context(long long * display, long long * shell)
{
    // create the initial context.
    HDC hdc = LongToHandle(*shell);
    HGLRC initialContext;
    int initial_pixelFormat = gs_get_initial_pixelformat(*shell);
    if (initial_pixelFormat != 0)
    {
        initialContext = wglCreateContext(hdc);
        if (initialContext != NULL)
        {
            if (!wglMakeCurrent(hdc, initialContext))
            {
                wglDeleteContext(initialContext);
                initialContext = NULL;
            }
        }
    }
    if (initialContext == NULL)
    {
        return 0; // failed to get even a simple context.
    }

    // now that there is a context, bind the opengl extensions and fail
    // if the supported extensions are too old or if they are not there.
    gs_wglGetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC) wglGetProcAddress( "wglGetExtensionsStringEXT" );
    gs_wglSwapIntervalARB = (PFNWGLSWAPINTERVALEXTPROC) wglGetProcAddress( "wglSwapIntervalEXT" );
    gs_wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC) wglGetProcAddress( "wglGetExtensionsStringARB" );
    gs_wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC) wglGetProcAddress( "wglCreateContextAttribsARB" );
    gs_wglGetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC) wglGetProcAddress( "wglGetPixelFormatAttribivARB" );
    gs_wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC) wglGetProcAddress( "wglChoosePixelFormatARB" );
    if (gs_wglGetExtensionsStringEXT == NULL ||
        gs_wglSwapIntervalARB ==  NULL ||
        gs_wglGetExtensionsStringARB ==  NULL ||
        gs_wglCreateContextAttribsARB ==  NULL ||
        gs_wglGetPixelFormatAttribivARB ==  NULL ||
        gs_wglChoosePixelFormatARB ==  NULL)
    {
        return 0;
    }

    // destroy and recreate the window and shell
    LPSTR gs_className = TEXT("GS_WIN");
    gs_display_dispose(*display);
    HMODULE hInstance = GetModuleHandle(NULL);
    *display = gs_create_window(hInstance, gs_className);
    *shell = gs_shell(*display);
    int pixelformat = gs_get_pixelformat(*shell);
    if (pixelformat == 0)
    {
        return 0;
    }

    // now create the context on the fresh window.
    int cnt = 0;
    int attribs[40];
    hdc = LongToHandle(*shell);

    // Use the expected baseline opengl 3.2
    attribs[cnt++] = WGL_CONTEXT_MAJOR_VERSION_ARB;
    attribs[cnt++] = 3;
    attribs[cnt++] = WGL_CONTEXT_MINOR_VERSION_ARB;
    attribs[cnt++] = 2;
    attribs[cnt++] = WGL_CONTEXT_FLAGS_ARB;
    attribs[cnt++] = WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
    attribs[cnt++] = WGL_CONTEXT_PROFILE_MASK_ARB;
    attribs[cnt++] = WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
    attribs[cnt++] = 0;
    HGLRC context = gs_wglCreateContextAttribsARB( hdc, NULL, attribs );
    if (context != NULL)
    {
        if (wglMakeCurrent(hdc, context))
        {
            return HandleToLong(context);
        }
    }
    return 0; // failed to get rendering context
}
예제 #7
0
static void test_ShellWindows(void)
{
    IShellWindows *shellwindows;
    LONG cookie, cookie2, ret;
    IDispatch *disp;
    VARIANT v, v2;
    HRESULT hr;
    HWND hwnd;

    hr = CoCreateInstance(&CLSID_ShellWindows, NULL, CLSCTX_LOCAL_SERVER,
                          &IID_IShellWindows, (void**)&shellwindows);
    ok(hr == S_OK, "got 0x%08x\n", hr);
    /* TODO: remove when explorer startup with clean prefix is fixed */
    if (hr != S_OK)
        return;

    if (0) { /* NULL out argument - currently crashes on Wine */
        hr = IShellWindows_Register(shellwindows, NULL, 0, SWC_EXPLORER, NULL);
        ok(hr == HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER), "got 0x%08x\n", hr);
    }
    hr = IShellWindows_Register(shellwindows, NULL, 0, SWC_EXPLORER, &cookie);
    todo_wine
    ok(hr == E_POINTER, "got 0x%08x\n", hr);

    hr = IShellWindows_Register(shellwindows, (IDispatch*)shellwindows, 0, SWC_EXPLORER, &cookie);
    todo_wine
    ok(hr == E_POINTER, "got 0x%08x\n", hr);

    hr = IShellWindows_Register(shellwindows, (IDispatch*)shellwindows, 0, SWC_EXPLORER, &cookie);
    todo_wine
    ok(hr == E_POINTER, "got 0x%08x\n", hr);

    hwnd = CreateWindowExA(0, "button", "test", BS_CHECKBOX | WS_VISIBLE | WS_POPUP,
                           0, 0, 50, 14, 0, 0, 0, NULL);
    ok(hwnd != NULL, "got %p, error %d\n", hwnd, GetLastError());

    cookie = 0;
    hr = IShellWindows_Register(shellwindows, NULL, HandleToLong(hwnd), SWC_EXPLORER, &cookie);
    todo_wine {
        ok(hr == S_OK, "got 0x%08x\n", hr);
        ok(cookie != 0, "got %d\n", cookie);
    }
    cookie2 = 0;
    hr = IShellWindows_Register(shellwindows, NULL, HandleToLong(hwnd), SWC_EXPLORER, &cookie2);
    todo_wine {
        ok(hr == S_OK, "got 0x%08x\n", hr);
        ok(cookie2 != 0 && cookie2 != cookie, "got %d\n", cookie2);
    }
    hr = IShellWindows_Revoke(shellwindows, cookie);
    todo_wine
    ok(hr == S_OK, "got 0x%08x\n", hr);
    hr = IShellWindows_Revoke(shellwindows, cookie2);
    todo_wine
    ok(hr == S_OK, "got 0x%08x\n", hr);

    hr = IShellWindows_Revoke(shellwindows, 0);
    todo_wine
    ok(hr == S_FALSE, "got 0x%08x\n", hr);

    /* we can register ourselves as desktop, but FindWindowSW still returns real desktop window */
    cookie = 0;
    hr = IShellWindows_Register(shellwindows, NULL, HandleToLong(hwnd), SWC_DESKTOP, &cookie);
    todo_wine {
        ok(hr == S_OK, "got 0x%08x\n", hr);
        ok(cookie != 0, "got %d\n", cookie);
    }
    disp = (void*)0xdeadbeef;
    ret = 0xdead;
    VariantInit(&v);
    hr = IShellWindows_FindWindowSW(shellwindows, &v, &v, SWC_DESKTOP, &ret, SWFO_NEEDDISPATCH, &disp);
    ok(hr == S_OK || broken(hr == S_FALSE), "got 0x%08x\n", hr);
    if (hr == S_FALSE) { /* winxp and earlier */
        win_skip("SWC_DESKTOP is not supported, some tests will be skipped.\n");
        /* older versions allowed to regiser SWC_DESKTOP and access it with FindWindowSW */
        ok(disp == NULL, "got %p\n", disp);
        ok(ret == 0, "got %d\n", ret);
    }
    else {
        static const IID *browser_riids[] = {
            &IID_IWebBrowser2,
            &IID_NULL
        };

        static const IID *viewdual_riids[] = {
            &IID_IShellFolderViewDual3,
            &IID_NULL
        };

        IShellFolderViewDual *view;
        IShellBrowser *sb, *sb2;
        IServiceProvider *sp;
        IDispatch *doc, *app;
        IWebBrowser2 *wb;
        IShellView *sv;
        IUnknown *unk;

        ok(disp != NULL, "got %p\n", disp);
        ok(ret != HandleToUlong(hwnd), "got %d\n", ret);

        /* IDispatch-related tests */
        test_dispatch_typeinfo(disp, browser_riids);

        /* IWebBrowser2 */
        hr = IDispatch_QueryInterface(disp, &IID_IWebBrowser2, (void**)&wb);
        ok(hr == S_OK, "got 0x%08x\n", hr);

        hr = IWebBrowser2_Refresh(wb);
        todo_wine
        ok(hr == S_OK, "got 0x%08x\n", hr);

        hr = IWebBrowser2_get_Application(wb, &app);
        ok(hr == S_OK, "got 0x%08x\n", hr);
        ok(disp == app, "got %p, %p\n", app, disp);
        IDispatch_Release(app);

        hr = IWebBrowser2_get_Document(wb, &doc);
        todo_wine
        ok(hr == S_OK, "got 0x%08x\n", hr);
        if (hr == S_OK)
            test_dispatch_typeinfo(doc, viewdual_riids);

        IWebBrowser2_Release(wb);

        /* IServiceProvider */
        hr = IDispatch_QueryInterface(disp, &IID_IShellFolderViewDual, (void**)&view);
        ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr);

        hr = IDispatch_QueryInterface(disp, &IID_IServiceProvider, (void**)&sp);
        ok(hr == S_OK, "got 0x%08x\n", hr);

        hr = IServiceProvider_QueryService(sp, &SID_STopLevelBrowser, &IID_IShellBrowser, (void**)&sb);
        ok(hr == S_OK, "got 0x%08x\n", hr);

        hr = IServiceProvider_QueryService(sp, &SID_STopLevelBrowser, &IID_IShellBrowser, (void**)&sb2);
        ok(hr == S_OK, "got 0x%08x\n", hr);
        ok(sb == sb2, "got %p, %p\n", sb, sb2);

        hr = IServiceProvider_QueryService(sp, &SID_STopLevelBrowser, &IID_IOleWindow, (void**)&unk);
        ok(hr == S_OK, "got 0x%08x\n", hr);
        IUnknown_Release(unk);

        hr = IServiceProvider_QueryService(sp, &SID_STopLevelBrowser, &IID_IExplorerBrowser, (void**)&unk);
        ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr);

        hr = IShellBrowser_QueryInterface(sb, &IID_IExplorerBrowser, (void**)&unk);
        ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr);

        hr = IShellBrowser_QueryInterface(sb, &IID_IWebBrowser2, (void**)&unk);
        ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr);

        hr = IShellBrowser_QueryInterface(sb, &IID_IDispatch, (void**)&unk);
        ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr);

        hr = IShellBrowser_QueryActiveShellView(sb, &sv);
        ok(hr == S_OK, "got 0x%08x\n", hr);
        IShellView_Release(sv);

        IShellBrowser_Release(sb2);
        IShellBrowser_Release(sb);

        hr = IServiceProvider_QueryService(sp, &SID_STopLevelBrowser, &IID_IUnknown, (void**)&unk);
        ok(hr == S_OK, "got 0x%08x\n", hr);

        hr = IUnknown_QueryInterface(unk, &IID_IShellBrowser, (void**)&sb2);
        ok(hr == S_OK, "got 0x%08x\n", hr);
        IShellBrowser_Release(sb2);
        IUnknown_Release(unk);

        hr = IServiceProvider_QueryService(sp, &SID_STopLevelBrowser, &IID_IShellView, (void**)&sv);
        ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr);

        IServiceProvider_Release(sp);
        IDispatch_Release(disp);
    }

    disp = (void*)0xdeadbeef;
    ret = 0xdead;
    VariantInit(&v);
    hr = IShellWindows_FindWindowSW(shellwindows, &v, &v, SWC_DESKTOP, &ret, 0, &disp);
    ok(hr == S_OK || broken(hr == S_FALSE) /* winxp */, "got 0x%08x\n", hr);
    ok(disp == NULL, "got %p\n", disp);
    ok(ret != HandleToUlong(hwnd), "got %d\n", ret);

    disp = (void*)0xdeadbeef;
    ret = 0xdead;
    V_VT(&v) = VT_I4;
    V_I4(&v) = cookie;
    VariantInit(&v2);
    hr = IShellWindows_FindWindowSW(shellwindows, &v, &v2, SWC_BROWSER, &ret, SWFO_COOKIEPASSED, &disp);
    todo_wine
    ok(hr == S_FALSE, "got 0x%08x\n", hr);
    ok(disp == NULL, "got %p\n", disp);
    ok(ret == 0, "got %d\n", ret);

    hr = IShellWindows_Revoke(shellwindows, cookie);
    todo_wine
    ok(hr == S_OK, "got 0x%08x\n", hr);
    DestroyWindow(hwnd);
    IShellWindows_Release(shellwindows);
}
예제 #8
0
파일: systray.c 프로젝트: Endle/wine-mirror
/*************************************************************************
 * Shell_NotifyIconW			[SHELL32.298]
 */
BOOL WINAPI Shell_NotifyIconW(DWORD dwMessage, PNOTIFYICONDATAW nid)
{
    HWND tray;
    COPYDATASTRUCT cds;
    struct notify_data data_buffer;
    struct notify_data *data = &data_buffer;
    BOOL ret;

    TRACE("dwMessage = %d, nid->cbSize=%d\n", dwMessage, nid->cbSize);

    /* Validate the cbSize so that WM_COPYDATA doesn't crash the application */
    if (nid->cbSize != NOTIFYICONDATAW_V1_SIZE &&
            nid->cbSize != NOTIFYICONDATAW_V2_SIZE &&
            nid->cbSize != NOTIFYICONDATAW_V3_SIZE &&
            nid->cbSize != sizeof(NOTIFYICONDATAW))
    {
        NOTIFYICONDATAW newNid;

        WARN("Invalid cbSize (%d) - using only Win95 fields (size=%d)\n",
             nid->cbSize, NOTIFYICONDATAW_V1_SIZE);
        CopyMemory(&newNid, nid, NOTIFYICONDATAW_V1_SIZE);
        newNid.cbSize = NOTIFYICONDATAW_V1_SIZE;
        return Shell_NotifyIconW(dwMessage, &newNid);
    }

    tray = FindWindowExW(0, NULL, classname, NULL);
    if (!tray) return FALSE;

    cds.dwData = dwMessage;
    cds.cbData = sizeof(*data);
    memset( data, 0, sizeof(*data) );

    /* FIXME: if statement only needed because we don't support interprocess
     * icon handles */
    if (nid->uFlags & NIF_ICON)
    {
        ICONINFO iconinfo;
        BITMAP bmMask;
        BITMAP bmColour;
        LONG cbMaskBits;
        LONG cbColourBits = 0;
        char *buffer;

        if (!GetIconInfo(nid->hIcon, &iconinfo))
            goto noicon;

        if (!GetObjectW(iconinfo.hbmMask, sizeof(bmMask), &bmMask) ||
                (iconinfo.hbmColor && !GetObjectW(iconinfo.hbmColor, sizeof(bmColour), &bmColour)))
        {
            DeleteObject(iconinfo.hbmMask);
            if (iconinfo.hbmColor) DeleteObject(iconinfo.hbmColor);
            goto noicon;
        }

        cbMaskBits = (bmMask.bmPlanes * bmMask.bmWidth * bmMask.bmHeight * bmMask.bmBitsPixel + 15) / 16 * 2;
        if (iconinfo.hbmColor)
            cbColourBits = (bmColour.bmPlanes * bmColour.bmWidth * bmColour.bmHeight * bmColour.bmBitsPixel + 15) / 16 * 2;
        cds.cbData = sizeof(*data) + cbMaskBits + cbColourBits;
        buffer = HeapAlloc(GetProcessHeap(), 0, cds.cbData);
        if (!buffer)
        {
            DeleteObject(iconinfo.hbmMask);
            if (iconinfo.hbmColor) DeleteObject(iconinfo.hbmColor);
            return FALSE;
        }

        data = (struct notify_data *)buffer;
        memset( data, 0, sizeof(*data) );
        buffer += sizeof(*data);
        GetBitmapBits(iconinfo.hbmMask, cbMaskBits, buffer);
        if (!iconinfo.hbmColor)
        {
            data->width  = bmMask.bmWidth;
            data->height = bmMask.bmHeight / 2;
            data->planes = 1;
            data->bpp    = 1;
        }
        else
        {
            data->width  = bmColour.bmWidth;
            data->height = bmColour.bmHeight;
            data->planes = bmColour.bmPlanes;
            data->bpp    = bmColour.bmBitsPixel;
            buffer += cbMaskBits;
            GetBitmapBits(iconinfo.hbmColor, cbColourBits, buffer);
            DeleteObject(iconinfo.hbmColor);
        }
        DeleteObject(iconinfo.hbmMask);
    }

noicon:
    data->hWnd   = HandleToLong( nid->hWnd );
    data->uID    = nid->uID;
    data->uFlags = nid->uFlags;
    if (data->uFlags & NIF_MESSAGE)
        data->uCallbackMessage = nid->uCallbackMessage;
    if (data->uFlags & NIF_TIP)
        lstrcpynW( data->szTip, nid->szTip, sizeof(data->szTip)/sizeof(WCHAR) );
    if (data->uFlags & NIF_STATE)
    {
        data->dwState     = nid->dwState;
        data->dwStateMask = nid->dwStateMask;
    }
    if (data->uFlags & NIF_INFO)
    {
        lstrcpynW( data->szInfo, nid->szInfo, sizeof(data->szInfo)/sizeof(WCHAR) );
        lstrcpynW( data->szInfoTitle, nid->szInfoTitle, sizeof(data->szInfoTitle)/sizeof(WCHAR) );
        data->u.uTimeout  = nid->u.uTimeout;
        data->dwInfoFlags = nid->dwInfoFlags;
    }
    if (data->uFlags & NIF_GUID)
        data->guidItem = nid->guidItem;
    if (dwMessage == NIM_SETVERSION)
        data->u.uVersion = nid->u.uVersion;
    /* FIXME: balloon icon */

    cds.lpData = data;
    ret = SendMessageW(tray, WM_COPYDATA, (WPARAM)nid->hWnd, (LPARAM)&cds);
    if (data != &data_buffer) HeapFree( GetProcessHeap(), 0, data );
    return ret;
}