This is the mail archive of the
cygwin-xfree@cygwin.com
mailing list for the Cygwin XFree86 project.
proposing a different aproach for XwinClip (but need some help)
- From: "Joan Bertran" <jbertran at cirsa dot com>
- To: <cygwin-xfree at cygwin dot com>
- Date: Thu, 14 Mar 2002 11:17:54 +0100
- Subject: proposing a different aproach for XwinClip (but need some help)
Hi,
I have implemented a different aproach about
copying clipboard contents between XFree86 and Windows based on
the original xwinclip.
It's less automatic but allows the user to control when to copy.
There is a windows trayicon with a menu to copy from Windows
or from X11. As it is possible to have several Xfree running
connected to different XClients (machines) there is submenu
to select which client you want to use.
But i have a problem when copying from windows to X11
(only tested with Kde 2.2.1) the new selection added to the Klipper
is not "activated" (so no paste with mouse middle button )
and if i do a message loop for "selectionrequest"
events, it receives an infinite number of those events:
---
XLoop new event
xevent.xselectionrequest.property _QT_SELECTION
target type TARGETS 334
XLoop new event
xevent.xselectionrequest.property _QT_SELECTION
target type XA_STRING 31
...
---
The function that performs this is "CopyFromWindows"
Below is the code:
// Standard library headers
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
//
#include <dirent.h>
// X headers */
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/Xatom.h>
#include <X11/keysym.h>
//------------------------------------------------------------------
// Fixups to prevent collisions between Windows and X headers
#undef MINSHORT
#undef MAXSHORT
// Flags for Windows header options
#define NONAMELESSUNION
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
// Windows headers
#include <w32api/windows.h>
#include <w32api/windowsx.h>
#include <w32api/shellapi.h>
//-----------------------------------------------
#define MYWM_NOTIFYICON (WM_APP+100)
#define IDM_EXIT 1000
#define IDM_FROM 100
#define IDM_TO 200
#define ID_ICON_APP 1
#define ID_ICON_TRAY 4
#define MAX_DISPLAYS 9
//------------------------------------------------
#ifndef ARRAYSIZE
#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
#endif
// Application constants
#define WINDOW_CLASS "XWinClip"
#define WINDOW_TITLE "xwinclip"
// Global variables
BOOL DisplayIds[MAX_DISPLAYS] = {FALSE, };
//--------------------------------------------------------------------------
-------
// MS-Windows Global Vars
HINSTANCE ghInstance;
HINSTANCE ghResInst;
HMENU hPopupMnu;
HMENU hmToWin;
HMENU hmToX11;
HWND hAppWnd;
// Function prototypes
HWND CreateMessagingWindow(void);
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
lParam);
void DOStoUNIX (char *pszData, int iLength);
void UNIXtoDOS (unsigned char **ppszData, int iLength);
//---------
//--------------------------------------------------------------------------
-------
//--------------------------------------------------------------------------
-------
BOOL DoCopyFromX11(Display *pDisplay, Window iMyWindow, unsigned char
**ppszReturnData)
{
Atom atomReturnType;
Atom atomLocalProperty;
Atom atomUTF8String;
int iReturnFormat;
unsigned long ulReturnItems, ulReturnBytesLeft;
int iReturn;
BOOL GotIt;
// Local property to hold pasted data
atomLocalProperty = XInternAtom (pDisplay, "CYGX_CUT_BUFFER", False);
if (atomLocalProperty == None)
{
MessageBox(hAppWnd, "Could not create CYGX_CUT_BUFFER atom",
"XWinClip", MB_OK);
return FALSE;
}
iReturn = XConvertSelection (pDisplay, XA_PRIMARY, XA_STRING,
atomLocalProperty, iMyWindow, CurrentTime);
if (iReturn == BadAtom || iReturn == BadWindow)
{
printf ("From X11 - XConvertSelection () failed\n");
return FALSE;
}
GotIt = FALSE;
// Loop for X events
while (!GotIt)
{
XEvent xevent;
// Block until the next X event
XNextEvent (pDisplay, &xevent);
//printf("XLoop new event\n");
// Branch on the event type
switch (xevent.type)
{
case SelectionNotify:
GotIt = TRUE;
//printf("Getting Size of property of Window %d\n",
iMyWindow);
// Retrieve the size of the stored data
iReturn = XGetWindowProperty (pDisplay, iMyWindow,
atomLocalProperty,
0,
0, // Don't get data, just get size */
False,
AnyPropertyType,
&atomReturnType,
&iReturnFormat,
&ulReturnItems,
&ulReturnBytesLeft,
ppszReturnData);
if (iReturn != Success)
{
MessageBox(hAppWnd, "From X11 - XGetWindowProperty ()
failed", "XWinClip", MB_OK);
return FALSE;
}
//printf("From X11 - returned data %d left %d\n",
ulReturnItems, ulReturnBytesLeft);
if (ulReturnBytesLeft <= 0)
{
MessageBox(hAppWnd, "XGetWindowProperty() returned 0
bytes", "XWinClip", MB_OK);
return FALSE;
}
// Request the selection data
iReturn = XGetWindowProperty (pDisplay, iMyWindow,
atomLocalProperty,
0,
ulReturnBytesLeft,
False,
AnyPropertyType,
&atomReturnType,
&iReturnFormat,
&ulReturnItems,
&ulReturnBytesLeft,
ppszReturnData);
if (iReturn != Success)
{
MessageBox(hAppWnd, "SelectionNotify - XGetWindowProperty
() failed", "XWinClip", MB_OK);
return FALSE;
}
break;
default:
// ++ if GotIt = TRUE (some kind of timeout);
break;
}
}
//printf("exiting XLoop\n");
//printf("From X11 - returned data %s, %d\n", *ppszReturnData,
strlen(*ppszReturnData) );
return TRUE;
}
//--------------------------------------------------------------------------
-------
//--------------------------------------------------------------------------
-------
BOOL DoPasteToWindows(char *pszReturnData)
{
HGLOBAL hGlobal;
char *pszGlobalData;
BOOL result = TRUE;
// Access the Windows clipboard
if (!OpenClipboard (hAppWnd))
{
printf ("OpenClipboard () failed\n");
return FALSE;
}
// Take ownership of the Window clipboard
if (!EmptyClipboard ())
{
MessageBox(hAppWnd, "EmptyClipboard () failed", "XWinClip", MB_OK);
result = FALSE;
}
// Allocate global memory for the X clipboard data
if (result)
hGlobal = GlobalAlloc (GMEM_MOVEABLE, strlen(pszReturnData) + 1);
result = !(hGlobal == NULL);
// Obtain a pointer to the global memory
if (result)
pszGlobalData = GlobalLock(hGlobal);
else MessageBox(hAppWnd, "Could not lock global memory for clipboard
transfer",
"XWinClip", MB_OK);
result = !(pszGlobalData == NULL);
if (result)
{
// Copy the returned string into the global memory
strcpy(pszGlobalData, pszReturnData);
// Release the pointer to the global memory
GlobalUnlock(hGlobal);
pszGlobalData = NULL;
// Push the selection data to the Windows clipboard
SetClipboardData(CF_TEXT, hGlobal);
// NOTE: Do not try to free pszGlobalData, it is owned by
// Windows after the call to SetClipboardData ().
}
// Release the clipboard
if (!CloseClipboard ())
printf ("CloseClipboard () failed\n");
return(result);
}
//---------------------------------------------------------
//---------------------------------------------------------
void CopyFromX11(char * DisplayName)
{
Display *pDisplay;
Window iMyWindow;
unsigned char *pszReturnData = NULL;
pDisplay = XOpenDisplay(DisplayName);
if (pDisplay == NULL)
{
MessageBox(hAppWnd, "Could not open display", "XWinClip", MB_OK);
return;
}
// Create a messaging window
iMyWindow = XCreateSimpleWindow (pDisplay,
RootWindow (pDisplay, 0),
1, 1,
500, 500,
0,
BlackPixel (pDisplay, 0),
BlackPixel (pDisplay, 0));
XFlush (pDisplay);
if (iMyWindow == 0)
{
MessageBox(hAppWnd, "Could not create a X11 window", "XWinClip", MB_OK);
}
else
{
XSelectInput (pDisplay, iMyWindow, ExposureMask);
if (DoCopyFromX11(pDisplay, iMyWindow, &pszReturnData) )
{
// Convert the X clipboard string to DOS format
UNIXtoDOS(&pszReturnData, strlen(pszReturnData));
DoPasteToWindows(pszReturnData);
// Free the data returned from XGetWindowProperty
XFree(pszReturnData);
pszReturnData = NULL;
}
XDestroyWindow (pDisplay, iMyWindow);
}
// Close the connection to X11
XCloseDisplay(pDisplay);
}
//--------------------------------------------------------------------------
----
//--------------------------------------------------------------------------
----
char * GetDisplayMachine(int DisplayNum)
{
static char buf[250];
Display *pDisplay;
Window iWindow;
Window root_return, parent_return;
Window *children_return;
int nchildren_return;
XTextProperty ClientMachine;
int iReturn;
sprintf(buf, ":%d.0", DisplayNum);
pDisplay = XOpenDisplay(buf);
if (pDisplay == NULL)
{
strncat(buf, " can't open display", sizeof(buf) -1 - 4);
return(buf);
}
iWindow = XDefaultRootWindow(pDisplay);
if ( (iWindow == BadWindow) || (iWindow == None) )
{
strncpy(buf, "Could not get Root Window", sizeof(buf) -1);
return(buf);
}
buf[0] = '\0';
XQueryTree(pDisplay, iWindow, &root_return, &parent_return,
&children_return, &nchildren_return);
if (nchildren_return > 0)
{
iWindow = children_return[0];
XFree(children_return);
}
else
{
return(buf);
}
iReturn = XGetWMClientMachine(pDisplay, iWindow, &ClientMachine);
if (iReturn == 0)
{
//strncpy(buf, "Could not get WMClientMachine", sizeof(buf) -1);
return(buf);
}
strncpy(buf, ClientMachine.value, sizeof(buf) -1);
XFree(ClientMachine.value);
XCloseDisplay(pDisplay);
buf[255] = '\0';
return(buf);
}
//--------------------------------------------------------------------------
----
void CopyFromWindows(char * DisplayName)
{
Display *pDisplay;
Window iWindow;
Window iMyWindow;
XSelectionEvent eventSelection;
int iReturn;
char *pszGlobalData;
HGLOBAL hGlobal;
Atom TargetsAtom;
//Atom atomClipboard;
Atom atomUTF8String;
BOOL XLoopDone = FALSE;
XTextProperty ClientMachine;
int i;
char * tmpstr;
BOOL IsSelectionRequest = FALSE;
pDisplay = XOpenDisplay(DisplayName);
if (pDisplay == NULL)
{
MessageBox(hAppWnd, "Could not open display", "XWinClip", MB_OK);
return;
}
// Create a messaging window
iMyWindow = XCreateSimpleWindow (pDisplay,
RootWindow (pDisplay, 0),
1, 1,
500, 500,
0,
BlackPixel (pDisplay, 0),
BlackPixel (pDisplay, 0));
if (iMyWindow == 0)
{
MessageBox(hAppWnd, "Could not create a X11 window", "XWinClip",
MB_OK);
}
XSelectInput (pDisplay, iMyWindow, StructureNotifyMask+ExposureMask);
XFlush (pDisplay);
atomUTF8String = XInternAtom (pDisplay, "UTF8_STRING", False);
if (atomUTF8String == None)
{
printf ("Could not create UTF8_STRING atom\n");
}
TargetsAtom = XInternAtom(pDisplay, "TARGETS", False);
if (TargetsAtom == None)
{
printf ("Could not create TARGETS atom\n");
// return;
}
iReturn = XSetSelectionOwner (pDisplay, XA_PRIMARY,
iMyWindow, CurrentTime);
if (iReturn == BadAtom || iReturn == BadWindow)
{
printf ("Could not set XA_PRIMARY owner to Our window\n");
}
while (!XLoopDone /*|| IsSelectionRequest*/ )
{
XEvent xevent;
XSelectionEvent eventSelection;
// Block until the next X event
XNextEvent(pDisplay, &xevent);
printf("\nXLoop new event\n");
// Branch on the event type
switch (xevent.type)
{
case SelectionRequest:
IsSelectionRequest = TRUE;
tmpstr = XGetAtomName(pDisplay,
xevent.xselectionrequest.property);
printf("xevent.xselectionrequest.property %s\n", tmpstr);
XFree(tmpstr);
tmpstr = NULL;
if (xevent.xselectionrequest.target == TargetsAtom)
{
Atom atTargetArr[2] = {atomUTF8String, XA_STRING};
XLoopDone = FALSE;
printf("target type TARGETS %d\n",
xevent.xselectionrequest.target);
iReturn = XChangeProperty (pDisplay,
xevent.xselectionrequest.requestor,
xevent.xselectionrequest.property,
xevent.xselectionrequest.target,
8,
PropModeReplace,
(char *)(atTargetArr),
sizeof(atTargetArr));
if (iReturn == BadAlloc || iReturn == BadAtom
|| iReturn == BadMatch || iReturn == BadValue
|| iReturn == BadWindow)
{
printf ("SelectionRequest - XChangeProperty failed: %d\n",
iReturn);
}
// Setup selection notify xevent
eventSelection.type = SelectionNotify;
eventSelection.send_event = True;
eventSelection.display = pDisplay;
eventSelection.requestor = xevent.xselectionrequest.requestor;
eventSelection.selection = xevent.xselectionrequest.selection;
eventSelection.target = xevent.xselectionrequest.target;
eventSelection.property = xevent.xselectionrequest.property;
eventSelection.time = xevent.xselectionrequest.time;
// Notify the requesting window that the operation has completed
iReturn = XSendEvent (pDisplay,
eventSelection.requestor,
False,
0L,
(XEvent *) &eventSelection);
if (iReturn == BadValue || iReturn == BadWindow)
{
printf ("XSendEvent () failed\n");
}
XFlush(pDisplay);
}
else if (xevent.xselectionrequest.target == XA_STRING)
{
printf("target type XA_STRING %d\n",
xevent.xselectionrequest.target);
XLoopDone = TRUE;
// Access the clipboard
if (!OpenClipboard (hAppWnd))
{
printf ("OpenClipboard () failed\n");
return;
}
// Get a pointer to the clipboard text
hGlobal = GetClipboardData (CF_TEXT);
if (!hGlobal)
{
printf ("GetClipboardData () failed\n");
return;
}
pszGlobalData = (char *) GlobalLock (hGlobal);
// Convert DOS string to UNIX string */
DOStoUNIX(pszGlobalData, strlen(pszGlobalData));
iReturn = XChangeProperty (pDisplay,
xevent.xselectionrequest.requestor,
xevent.xselectionrequest.property,
xevent.xselectionrequest.target,
8,
PropModeReplace,
pszGlobalData,
strlen(pszGlobalData) );
if (iReturn == BadAlloc || iReturn == BadAtom
|| iReturn == BadMatch || iReturn == BadValue
|| iReturn == BadWindow)
{
printf ("SelectionRequest - XChangeProperty failed: %d\n",
iReturn);
}
// Release the clipboard data
GlobalUnlock(hGlobal);
pszGlobalData = NULL;
CloseClipboard();
// Setup selection notify xevent
eventSelection.type = SelectionNotify;
eventSelection.send_event = True;
eventSelection.display = pDisplay;
eventSelection.requestor = xevent.xselectionrequest.requestor;
eventSelection.selection = xevent.xselectionrequest.selection;
eventSelection.target = xevent.xselectionrequest.target;
eventSelection.property = xevent.xselectionrequest.property;
eventSelection.time = xevent.xselectionrequest.time;
// Notify the requesting window that the operation has completed
iReturn = XSendEvent (pDisplay,
eventSelection.requestor,
False,
0L,
(XEvent *) &eventSelection);
if (iReturn == BadValue || iReturn == BadWindow)
{
printf ("XSendEvent () failed\n");
//return;
}
XFlush(pDisplay);
}
else
{
// Abort if invalid target type
XLoopDone = TRUE;
printf("invalid target type %d\n",
xevent.xselectionrequest.target);
// Setup selection notify xevent
eventSelection.type = SelectionNotify;
eventSelection.send_event = True;
eventSelection.display = pDisplay;
eventSelection.requestor = xevent.xselectionrequest.requestor;
eventSelection.selection = xevent.xselectionrequest.selection;
eventSelection.target = xevent.xselectionrequest.target;
eventSelection.property = None;
eventSelection.time = xevent.xselectionrequest.time;
// Notify the requesting window that the operation is complete
iReturn = XSendEvent (pDisplay,
eventSelection.requestor,
False,
0L,
(XEvent *) &eventSelection);
if (iReturn == BadValue || iReturn == BadWindow)
{
printf ("XSendEvent () failed\n");
//return;
}
XFlush(pDisplay);
/******************
iReturn = XSetSelectionOwner (pDisplay, XA_PRIMARY,
eventSelection.requestor, CurrentTime);
if (iReturn == BadAtom || iReturn == BadWindow)
{
printf ("Could not set XA_PRIMARY owner back to last
window\n");
}
XFlush(pDisplay);
**********/
}
break;
case SelectionClear:
IsSelectionRequest = FALSE;
printf("SelectionClear message handler\n");
break;
default:
IsSelectionRequest = FALSE;
printf("default message handler\n");
break;
} // case
} // while
XDestroyWindow(pDisplay, iMyWindow);
XCloseDisplay(pDisplay);
}
//---------------------------------------------------------
//---------------------------------------------
// * Change \n to \r\n. Reallocate string if necessary.
// ---------------------------------------------
void UNIXtoDOS (unsigned char **ppszData, int iLength)
{
int iNewlineCount = 0;
unsigned char *pszSrc = *ppszData;
unsigned char *pszEnd = pszSrc + iLength;
unsigned char *pszDest = NULL, *pszDestBegin = NULL;
#if 0
printf ("UNIXtoDOS () - Original data:\n%s\n", *ppszData);
#endif
// Count \n characters without leading \r */
while (pszSrc < pszEnd)
{
// Skip ahead two character if found set of \r\n */
if (*pszSrc == '\r' && pszSrc + 1 < pszEnd && *(pszSrc + 1) == '\n')
{
pszSrc += 2;
continue;
}
// Increment the count if found naked \n */
if (*pszSrc == '\n')
{
iNewlineCount++;
}
pszSrc++;
}
// Return if no naked \n's */
if (iNewlineCount == 0)
return;
// Allocate a new string */
pszDestBegin = pszDest = malloc (iLength + iNewlineCount + 1);
// Set source pointer to beginning of data string */
pszSrc = *ppszData;
// Loop through all characters in source string */
while (pszSrc < pszEnd)
{
// Copy line endings that are already valid */
if (*pszSrc == '\r' && pszSrc + 1 < pszEnd && *(pszSrc + 1) == '\n')
{
*pszDest = *pszSrc;
*(pszDest + 1) = *(pszSrc + 1);
pszDest += 2;
pszSrc += 2;
continue;
}
// Add \r to naked \n's */
if (*pszSrc == '\n')
{
*pszDest = '\r';
*(pszDest + 1) = *pszSrc;
pszDest += 2;
pszSrc += 1;
continue;
}
// Copy normal characters */
*pszDest = *pszSrc;
pszSrc++;
pszDest++;
}
// Put terminating null at end of new string */
*pszDest = '\0';
// Swap string pointers */
free (*ppszData);
*ppszData = pszDestBegin;
#if 0
printf ("UNIXtoDOS () - Final string:\n%s\n", pszDestBegin);
#endif
}
//--------------------------------------------------------------------------
--
// This was heavily inspired by, if not down right stolen from, Cygwin's
// winsup/cygwin/fhandler.cc/fhandler_base::read ()
//--------------------------------------------------------------------------
--
void DOStoUNIX (char *pszSrc, int iLength)
{
char *pszDest = pszSrc;
char *pszEnd = pszSrc + iLength;
// Loop until the last character */
while (pszSrc < pszEnd)
{
// Copy the current source character to current destination character
*/
*pszDest = *pszSrc;
// Advance to the next source character */
pszSrc++;
// Don't advance the destination character if we need to drop an \r */
if (*pszDest != '\r' || *pszSrc != '\n')
pszDest++;
}
// Move the terminating null */
*pszDest = '\0';
}
// -------------------------------------------------------------------------
-----------------
int main (int argc, char *argv[])
{
HWND hWnd;
MSG msg;
ghInstance = GetModuleHandle (NULL);
ghResInst = LoadLibraryEx(/*C:\\cygwinDEV\\xwinclip\\*/"XWinclip.DLL",
NULL, LOAD_LIBRARY_AS_DATAFILE);
printf("ghResInst = %d\n", ghResInst);
// Create Windows messaging window
hWnd = CreateMessagingWindow();
// Loop for Windows events
// Acquire and dispatch messages until a WM_QUIT message is received.
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
////printf("Exiting xwinclip\n");
CreateTrayIcon(hWnd, NIM_DELETE, 0, NULL, NULL);
FreeLibrary(ghResInst);
UnregisterClass(WINDOW_CLASS, ghInstance);
return 0;
}
//--------------------------------------------------------------------------
----
// supported only local Displays from 0 to 9
//--------------------------------------------------------------------------
----
int SelectDir(const struct dirent * current)
{
//(strlen(current->d_name) <= 2) &&
return (
(current->d_name[0] == 'X') &&
(current->d_name[1] >= '0') &&
(current->d_name[1] <= '9') &&
(current->d_name[2] == '\0')
);
}
//--------------------------------------------------------------------------
----
// to find displays
//--- /tpm/.X11-unix/X0 .. X4 .. Xn
//--------------------------------------------------------------------------
----
void RebuildTrayMenus(void)
{
char buf[260];
struct dirent **namelist;
int i, n;
for (i = 0; i < ARRAYSIZE(DisplayIds); i++)
{
if (DisplayIds[i])
{
DeleteMenu(hmToWin, 0, MF_BYPOSITION);
DeleteMenu(hmToX11, 0, MF_BYPOSITION);
}
}
i = scandir("/tmp/.X11-unix/", &namelist, SelectDir, alphasort);
if (i < 0)
printf("error scandir\n");
else
{
bzero( (void *)DisplayIds, sizeof(DisplayIds));
while (i--)
{
int n = namelist[i]->d_name[1] - '0';
DisplayIds[n] = TRUE;
/////////printf("%s\n", namelist[i]->d_name);
free(namelist[i]);
}
free(namelist);
}
for (i = 0; i < ARRAYSIZE(DisplayIds); i++)
{
if (DisplayIds[i])
{
char * MachineName = GetDisplayMachine(i);
sprintf(buf, "From %d (%s)", i, MachineName);
AppendMenu(hmToWin, MF_ENABLED | MF_STRING, IDM_FROM + i, buf);
sprintf(buf, "To %d (%s)", i, MachineName);
AppendMenu(hmToX11, MF_ENABLED | MF_STRING, IDM_TO + i, buf);
}
}
}
//--------------------------------------------------------------------------
----
//--------------------------------------------------------------------------
----
LRESULT CALLBACK WindowProc (HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM
lParam)
{
static BOOL bShowing = TRUE;
POINT Point;
int CommandId;
// cases for application messages
switch (uMessage)
{
// command from application menu
case WM_COMMAND:
//use the GET_WM_COMMAND macro to unpack the commnad
CommandId = GET_WM_COMMAND_ID(wParam, lParam);
if ( (CommandId >= IDM_FROM) && (CommandId < IDM_FROM +
MAX_DISPLAYS) )
{
// Copy From X11
char dispName[8];
sprintf(dispName, ":%d.0", CommandId - IDM_FROM);
CopyFromX11(dispName);
//printf("Done Copy From X11 %d\n", CommandId);
}
else if ( (CommandId >= IDM_TO) && (CommandId < IDM_TO +
MAX_DISPLAYS) )
{
// Copy To X11
char dispName[8];
sprintf(dispName, ":%d.0", CommandId - IDM_TO);
CopyFromWindows(dispName);
//printf("Done Copy To X11 %d\n", CommandId);
}
else if (CommandId == IDM_EXIT)
{
DestroyWindow(hWnd);
}
else
{
return DefWindowProc(hWnd, uMessage, wParam, lParam);
}
break;
case MYWM_NOTIFYICON:
switch (lParam)
{
case WM_LBUTTONDBLCLK:
if (bShowing)
{
ShowWindow(hWnd, SW_HIDE);
}
else
{
ShowWindow(hWnd, SW_SHOW);
SetForegroundWindow(hWnd); // make us come to the front
}
bShowing = !bShowing;
break;
/*case WM_LBUTTONDOWN:
switch (wParam)
{
}
break; */
case WM_RBUTTONDOWN:
RebuildTrayMenus();
DrawMenuBar(hWnd);
break;
case WM_RBUTTONUP:
GetCursorPos(&Point);
if ( !TrackPopupMenuEx(hPopupMnu,
/*TPM_RIGHTBUTTON |*/ TPM_RIGHTALIGN, //
screen-position and mouse-button flags
Point.x, Point.y, hWnd, NULL) // points to RECT
that specifies no-dismissal area
) printf("popup menu failed at X:%d, Y:%d\n",
Point.x, Point.y);
break;
default:
break;
}
break;
case WM_DESTROY: // message: window being destroyed
PostQuitMessage(0);
break;
default: // Passes it on if unproccessed
return DefWindowProc(hWnd, uMessage, wParam, lParam);
}
return 0;
}
//--------------------------------------------------------------------------
----------------
//--------------------------------------------------------------------------
-
BOOL CreateTrayIcon(HWND hWnd, DWORD dwMessage, UINT uID, HICON hIcon, PSTR
pszTip)
{
BOOL res;
NOTIFYICONDATA tnd;
tnd.cbSize = sizeof(NOTIFYICONDATA);
tnd.hWnd = hWnd;
tnd.uID = uID;
tnd.uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP;
tnd.uCallbackMessage = MYWM_NOTIFYICON;
tnd.hIcon = hIcon;
if (pszTip)
{
lstrcpyn(tnd.szTip, pszTip, sizeof(tnd.szTip));
}
else
{
tnd.szTip[0] = '\0';
}
res = Shell_NotifyIcon(dwMessage, &tnd);
return res;
}
//--------------------------------------------------------------------------
---
void CreateTrayMenu(void)
{
hPopupMnu = CreatePopupMenu();
hmToWin = CreatePopupMenu();
hmToX11 = CreatePopupMenu();
AppendMenu(hPopupMnu, MF_ENABLED | MF_POPUP | MF_STRING, (UINT)hmToWin,
"Copy TO Windows");
AppendMenu(hPopupMnu, MF_ENABLED | MF_POPUP | MF_STRING, (UINT)hmToX11,
"Copy TO X11");
AppendMenu(hPopupMnu, MF_SEPARATOR, 0, NULL);
AppendMenu(hPopupMnu, MF_ENABLED | MF_STRING, IDM_EXIT, "Exit (Alt+F4)");
}
//--------------------------------------------------------------------------
---
HWND CreateMessagingWindow(void)
{
WNDCLASS wc;
HICON hIconApp;
HICON hIconTray;
hIconApp = (HICON)LoadImage(ghResInst, MAKEINTRESOURCE(ID_ICON_APP),
IMAGE_ICON, 16, 16, 0);
hIconTray = (HICON)LoadImage(ghResInst, MAKEINTRESOURCE(ID_ICON_TRAY),
IMAGE_ICON, 16, 16, 0);
//printf("hIconApp = %d\n", hIconApp);
//printf("hIconTray = %d\n", hIconTray);
CreateTrayMenu();
//printf("hPopupMnu %d\n", hPopupMnu);
// Setup our window class */
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = ghInstance;
wc.hIcon = hIconApp;
wc.hCursor = 0;
wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = WINDOW_CLASS;
RegisterClass (&wc);
// Create the window
hAppWnd = CreateWindowExA (0, // Extended styles
WINDOW_CLASS, // Class name
WINDOW_TITLE, // Window name
WS_OVERLAPPED, // Not visible anyway
CW_USEDEFAULT, // Horizontal position
CW_USEDEFAULT, // Vertical position
50, // Right edge CW_USEDEFAULT
50, // Bottom edge CW_USEDEFAULT
(HWND) NULL, // No parent or owner window
(HMENU) NULL, // No menu
ghInstance,// Instance handle
NULL); // ScreenPrivates
assert (hAppWnd != NULL);
CreateTrayIcon(hAppWnd, NIM_ADD, 0, hIconTray, "XClipboard 2 Win");
return(hAppWnd);
}
Any advice ?
Thanks.