soc.2009.vulture: 50435feb: Send messages from already-existing IM w...

gdick at soc.pidgin.im gdick at soc.pidgin.im
Tue Jun 16 17:05:33 EDT 2009


-----------------------------------------------------------------
Revision: 50435feb4e7881f8320a5e74877be9bf1b8e2d29
Ancestor: 2aa76746edd800cfa0e64e30444ade2efac600f0
Author: gdick at soc.pidgin.im
Date: 2009-06-16T15:46:18
Branch: im.pidgin.soc.2009.vulture
URL: http://d.pidgin.im/viewmtn/revision/info/50435feb4e7881f8320a5e74877be9bf1b8e2d29

Modified files:
        vulture/purpleconv.c vulture/purpleconv.h
        vulture/purplequeue.c vulture/purplequeue.h
        vulture/vultureblist.h vulture/vultureconv.c
        vulture/vultureconv.h

ChangeLog: 

Send messages from already-existing IM windows.

-------------- next part --------------
============================================================
--- vulture/purpleconv.c	63db9ef121a1e48bb22c6a04e53b38d8a70b7262
+++ vulture/purpleconv.c	2a67703f1d2bc79b3ce328b2ed3a018e0737ae8b
@@ -121,3 +121,22 @@ void VultureFreeConvWrite(VULTURE_CONV_W
 	g_free(lpvcwrite->szName);
 	g_free(lpvcwrite);
 }
+
+
+/**
+ * Sends a message.
+ *
+ * @param	lpvcsend	Details of message to send.
+ */
+void PurpleConversationSend(VULTURE_CONV_SEND *lpvcsend)
+{
+	char *szMessage = VultureTCHARToUTF8(lpvcsend->szMessage);
+
+	/* Send to IM or chat, as appropriate. */
+	if(lpvcsend->lpvconv->lpconv->type == PURPLE_CONV_TYPE_IM)
+		purple_conv_im_send(lpvcsend->lpvconv->lpconv->u.im, szMessage);
+	else
+		purple_conv_chat_send(lpvcsend->lpvconv->lpconv->u.chat, szMessage);
+
+	g_free(szMessage);
+}
============================================================
--- vulture/purpleconv.h	179fbac52e7e65785d3c2bbc8615d6e05183c69b
+++ vulture/purpleconv.h	15c00fd98e50f6dd029e6fa225c198bbd958fae6
@@ -32,6 +32,7 @@ void VultureFreeConvWrite(VULTURE_CONV_W
 void PurpleDestroyConversation(PurpleConversation *lpconv);
 void PurpleWriteConversation(PurpleConversation *lpconv, const char *szName, const char *szAlias, const char *szMessage, PurpleMessageFlags pmflags, time_t timeMsg);
 void VultureFreeConvWrite(VULTURE_CONV_WRITE *lpvcwrite);
+void PurpleConversationSend(VULTURE_CONV_SEND *lpvcsend);
 
 
 #endif
============================================================
--- vulture/purplequeue.c	b9518c2ba9a6cc5bce22c1dad72a500fbe4cb1d2
+++ vulture/purplequeue.c	ed5c141acc28adef6c4327dbee4d57510c0b1667
@@ -29,6 +29,7 @@
 #include "purplestatus.h"
 #include "purpleacct.h"
 #include "vultureconv.h"
+#include "purpleconv.h"
 
 
 /** Queue node representing a libpurple call. */
@@ -191,6 +192,11 @@ static void DispatchPurpleCall(PURPLE_CA
 		purple_conversation_destroy(((VULTURE_CONVERSATION*)lppurplecall->lpvParam)->lpconv);
 		break;
 
+	case PC_CONVSEND:
+		PurpleConversationSend((VULTURE_CONV_SEND*)lppurplecall->lpvParam);
+		VultureFreeConvSend((VULTURE_CONV_SEND*)lppurplecall->lpvParam);
+		break;
+
 	case PC_QUIT:
 		purple_core_quit();
 		g_main_loop_quit(g_lpgmainloop);
============================================================
--- vulture/purplequeue.h	fdb22c8699d897885c9a8f245d0ae277a2aa60ef
+++ vulture/purplequeue.h	f6087cbcaf4678c2e64889beee6e3ae7d05d57b8
@@ -53,6 +53,9 @@ enum PURPLE_CALL_ID
 
 	/* (VULTURE_CONVERSATION*) Conversation to destroy. */
 	PC_DESTROYCONVERSATION,
+
+	/* (VULTURE_CONV_SEND*) Conversation send-message details. */
+	PC_CONVSEND,
 };
 
 
============================================================
--- vulture/vultureblist.h	e6ed29d75ce6780b1837f9f4069b0270d7d73990
+++ vulture/vultureblist.h	aab4c2eb4b9d1a0420a8d1b295c54b24af1f56dc
@@ -37,9 +37,6 @@ typedef struct _VULTURE_BLIST_NODE
 } VULTURE_BLIST_NODE;
 
 
-#define WM_PURPLEUIMSG	WM_APP
-
-
 extern HWND g_hwndMain;
 GList *g_lpglistConvContainers;
 
============================================================
--- vulture/vultureconv.c	65e7a7555078218abbde90f2e9594d434e3ff725
+++ vulture/vultureconv.c	f08946df5b39fd4cddab526e2109e799a22f6bac
@@ -53,6 +53,7 @@ static void RepositionConvControls(HWND 
 static INT_PTR CALLBACK IMDlgProc(HWND hwndDlg, UINT uiMsg, WPARAM wParam, LPARAM lParam);
 static void ResizeConversationWindows(HWND hwndConvContainer, HWND hwndTabs);
 static void RepositionConvControls(HWND hwndConvDlg);
+static LRESULT CALLBACK InputBoxSubclassProc(HWND hwnd, UINT uiMsg, WPARAM wParam, LPARAM lParam);
 
 
 /**
@@ -162,7 +163,7 @@ static LRESULT CALLBACK ConvContainerWnd
 				LeaveCriticalSection(&lpvconv->sync.cs);
 
 				/* Create conversation dialogue. */
-				lpvconv->hwndConv = CreateDialog(g_hInstance, MAKEINTRESOURCE(IDD_IM), hwndTabs, IMDlgProc);
+				lpvconv->hwndConv = CreateDialogParam(g_hInstance, MAKEINTRESOURCE(IDD_IM), hwndTabs, IMDlgProc, (LPARAM)lpvconv);
 
 				ResizeConversationWindows(hwnd, hwndTabs);
 			}
@@ -363,12 +364,61 @@ static INT_PTR CALLBACK IMDlgProc(HWND h
  */
 static INT_PTR CALLBACK IMDlgProc(HWND hwndDlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
 {
+	VULTURE_CONVERSATION *lpvconv;
+
 	switch(uiMsg)
 	{
 	case WM_INITDIALOG:
+		{
+			HWND hwndREInput = GetDlgItem(hwndDlg, IDC_RICHEDIT_INPUT);
+
+			/* Remember the conversation. */
+			lpvconv = (VULTURE_CONVERSATION*)lParam;
+			SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam);
+
+			/* Subclass the input box. */
+			lpvconv->wndprocInputOrig = (WNDPROC)GetWindowLongPtr(hwndREInput, GWLP_WNDPROC);
+			SetWindowLongPtr(hwndREInput, GWLP_WNDPROC, (LONG)InputBoxSubclassProc);
+		}
+		
 		/* Let the system set the focus. */
 		return TRUE;
 
+	case WM_INPUTENTER:
+		/* User pressed Enter in input box. Send message. */
+		if(GetWindowTextLength((HWND)lParam) > 0)
+		{
+			VULTURE_CONV_SEND *lpvcsend = ProcHeapAlloc(sizeof(VULTURE_CONV_SEND));
+			GETTEXTLENGTHEX gtlex;
+			GETTEXTEX gettextex;
+			int cchInput;
+
+#ifdef UNICODE
+			const UINT c_codepage = 1200;
+#else
+			const UINT c_codepage = CP_ACP;
+#endif
+
+			gtlex.flags = GTL_CLOSE | GTL_NUMCHARS;
+			gtlex.codepage = c_codepage;
+			cchInput = SendMessage((HWND)lParam, EM_GETTEXTLENGTHEX, (WPARAM)&gtlex, 0) + 1;
+			lpvcsend->szMessage = ProcHeapAlloc(cchInput * sizeof(TCHAR));
+
+			gettextex.cb = cchInput * sizeof(TCHAR);
+			gettextex.codepage = c_codepage;
+			gettextex.flags = GT_DEFAULT;
+			gettextex.lpDefaultChar = NULL;
+			gettextex.lpUsedDefChar = NULL;
+			SendMessage((HWND)lParam, EM_GETTEXTEX, (WPARAM)&gettextex, (LPARAM)lpvcsend->szMessage);
+
+			SetWindowText((HWND)lParam, TEXT(""));
+
+			lpvcsend->lpvconv = (VULTURE_CONVERSATION*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+			VultureEnqueueAsyncPurpleCall(PC_CONVSEND, lpvcsend);
+		}
+
+		return TRUE;
+
 	case WM_SIZE:
 		RepositionConvControls(hwndDlg);
 		return TRUE;
@@ -484,3 +534,44 @@ void VultureWriteConversation(VULTURE_CO
 	SendMessage(hwndRichEdit, EM_REPLACESEL, 0, (LPARAM)lpvcwrite->szMessage);
 	SendMessage(hwndRichEdit, EM_REPLACESEL, 0, (LPARAM)TEXT("\n"));
 }
+
+
+/**
+ * Subclassing window procedure for input Rich Edit control in conversation
+ * windows.
+ *
+ * @param	hwnd		Input box window handle.
+ * @param	uiMsg		Message ID.
+ * @param	wParam		Message-specific.
+ * @param	lParam		Message-specific.
+ *
+ * @return Message-specific.
+ */
+static LRESULT CALLBACK InputBoxSubclassProc(HWND hwnd, UINT uiMsg, WPARAM wParam, LPARAM lParam)
+{
+	VULTURE_CONVERSATION *lpvconv;
+	HWND hwndParent = GetParent(hwnd);
+
+	/* Intercept the Enter key. */
+	if(uiMsg == WM_KEYDOWN && wParam == VK_RETURN && !(GetKeyState(VK_SHIFT) & 0x8000))
+	{
+		SendMessage(hwndParent, WM_INPUTENTER, 0, (LPARAM)hwnd);
+		return 0;
+	}
+
+	lpvconv = (VULTURE_CONVERSATION*)GetWindowLongPtr(hwndParent, GWLP_USERDATA);
+	return CallWindowProc(lpvconv->wndprocInputOrig, hwnd, uiMsg, wParam, lParam);
+}
+
+
+/**
+ * Called by the core to free the data allocated when sending a message when
+ * it's done with it.
+ *
+ * @param	lpvcsend	Data to free.
+ */
+void VultureFreeConvSend(VULTURE_CONV_SEND *lpvcsend)
+{
+	ProcHeapFree(lpvcsend->szMessage);
+	ProcHeapFree(lpvcsend);
+}
============================================================
--- vulture/vultureconv.h	b925a4754761ef46f695dfc2b837f09b772340da
+++ vulture/vultureconv.h	ca2cea87404b2370cf5432b9f4776aab779e637c
@@ -35,6 +35,7 @@ typedef struct _VULTURE_CONVERSATION
 	HWND			hwndConv;
 	HWND			hwndContainer;
 	int			iTabIndex;
+	WNDPROC			wndprocInputOrig;
 
 	/* Data still needed by the core thread after initialisation. */
 	struct
@@ -53,10 +54,17 @@ typedef struct _VULTURE_CONV_WRITE
 	SYSTEMTIME		systimeMsg;
 } VULTURE_CONV_WRITE;
 
+typedef struct _VULTURE_CONV_SEND
+{
+	VULTURE_CONVERSATION	*lpvconv;
+	LPTSTR			szMessage;
+} VULTURE_CONV_SEND;
 
+
 int VultureRegisterConvContainerWindowClass(void);
 HWND VultureCreateConvContainer(void);
 void VultureWriteConversation(VULTURE_CONV_WRITE *lpvcwrite);
+void VultureFreeConvSend(VULTURE_CONV_SEND *lpvcsend);
 
 
 #endif


More information about the Commits mailing list