/* CLIDEMO is a simple program demonstrating how to establish a DDE connection with WorldView and use it to send CLI commands. It is provided purely as programming example, not as a supported product. */ #include #include #include #include "clidemo.h" LRESULT PASCAL WndProc(HWND, UINT, WPARAM, LPARAM); LRESULT FAR PASCAL EditProc(HWND, UINT, WPARAM, LPARAM); HDDEDATA EXPENTRY DdeCallback(WORD, WORD, HCONV, HSZ, HSZ, HDDEDATA, DWORD, DWORD); DWORD idInst = 0L; HSZ hszServerName; HSZ hszTopic; HSZ hszResult; HSZ hszIntmes; HCONV hConversation; FARPROC lpfnOldEditProc; FARPROC lpfnEditProc; HWND hwndMain; int item_count; HWND hwndRes; /* Free up the DDE strings we declared. */ void FreeStrings() { DdeFreeStringHandle(idInst, hszServerName); DdeFreeStringHandle(idInst, hszTopic); DdeFreeStringHandle(idInst, hszResult); DdeUninitialize(idInst); } /* Because results from CLI contain LFs (Unix standard) instead of CR/LFs (DOS standard), we have to filter the result while sending it to the control. */ void SendTextToEditControl(LPSTR szText) { int st_count; if (item_count > 150) { SendMessage(hwndRes, LB_RESETCONTENT, 0, 0L); item_count = 0; } st_count = item_count; for(szText = strtok(szText, "\n"); szText != NULL; szText = strtok(NULL, "\n")) { SendMessage(hwndRes, LB_ADDSTRING, 0, (LPARAM)(LPSTR) szText); item_count++; } SendMessage(hwndRes, LB_SETTOPINDEX, (WORD)st_count, 0L); return; } int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) { static char szAppName[] = "CliDemo"; MSG msg; WNDCLASS wndclass; FARPROC lpDdeProc; HWND hwndCommand; if(!hPrevInstance) { wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = DLGWINDOWEXTRA; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(hInstance, szAppName); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szAppName; RegisterClass(&wndclass); } lpDdeProc = MakeProcInstance((FARPROC) DdeCallback, hInstance); lpfnEditProc = MakeProcInstance((FARPROC) EditProc, hInstance); /* Initialize DDE, create the strings, and connect with WorldView. */ if(DdeInitialize(&idInst, (PFNCALLBACK) lpDdeProc, CBF_FAIL_EXECUTES | CBF_FAIL_POKES, 0L)) return(NULL); hszServerName = DdeCreateStringHandle(idInst, "WorldView", CP_WINANSI); hszTopic = DdeCreateStringHandle(idInst, "CLI", CP_WINANSI); hszResult = DdeCreateStringHandle(idInst, "Result", CP_WINANSI); hszIntmes = DdeCreateStringHandle(idInst, "Intmes", CP_WINANSI); hConversation = (HCONV)DdeConnect((DWORD)idInst, (HSZ)hszServerName, (HSZ)hszTopic, (CONVCONTEXT FAR *) NULL); if (hConversation == (HCONV)NULL) { WinExec("\\cxview\\run\\mswv.exe", SW_SHOWNORMAL); hConversation = (HCONV)DdeConnect((DWORD)idInst, (HSZ)hszServerName, (HSZ)hszTopic, (CONVCONTEXT FAR *) NULL); if (hConversation == (HCONV)NULL) { MessageBox(NULL, "Unable to start and/or connect with WorldView.", "Error", MB_OK); FreeStrings(); return(NULL); } } DdeClientTransaction ((void FAR *)NULL, (DWORD)0, (HSZ)hConversation, (HSZ)hszIntmes, CF_TEXT, XTYP_ADVSTART, (DWORD)TIMEOUT_ASYNC, (DWORD FAR *)NULL); hwndMain = CreateDialog(hInstance, szAppName, HWND_DESKTOP, NULL); /* Replace the edit control's prodedure with our own (which calls the original procedure). This allows us to catch the ENTER key and respond to it. */ hwndCommand = GetDlgItem(hwndMain, ID_COMMAND); hwndRes = GetDlgItem(hwndMain, ID_RESULT); lpfnOldEditProc = (FARPROC) GetWindowLong(hwndCommand, GWL_WNDPROC); SetWindowLong(hwndCommand, GWL_WNDPROC, (LONG) lpfnEditProc); SendMessage (hwndRes, LB_SETHORIZONTALEXTENT, 4000, 0L); item_count = 0; ShowWindow(hwndMain, nCmdShow); while(GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } if(hConversation != (HSZ)NULL) DdeDisconnect(hConversation); FreeStrings(); return(msg.wParam); } /* Since the client initiates most of the DDE exchange, the callback function can be simple. */ HDDEDATA EXPENTRY DdeCallback(WORD wType, WORD wFmt, HCONV hConv, HSZ hsz1, HSZ hsz2, HDDEDATA hData, DWORD dwData1, DWORD dwData2) { LPBYTE lpdata; char buf[200]; DWORD len; switch(wType) { case XTYP_DISCONNECT : /* If WorldView disconnects (because it exits), we'll exit too. */ hConversation = NULL; DestroyWindow(hwndMain); return((HDDEDATA) NULL); case XTYP_ADVDATA : lpdata = DdeAccessData (hData, &len); if ((lpdata == (LPBYTE)NULL) || (len == (DWORD)0)) return (DDE_FNOTPROCESSED); SendTextToEditControl (lpdata); DdeUnaccessData (hData); return ((HDDEDATA) TRUE); default: return((HDDEDATA) NULL); } } #define MAX_COMMAND 1024 LRESULT FAR PASCAL WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { DWORD dwResult; int iLen; char szBuffer[MAX_COMMAND+1]; HDDEDATA hResult; switch(message) { case WM_CREATE : return FALSE; case WM_COMMAND : switch(LOWORD(wParam)) { case ID_EXECUTE : /* Get text from edit control. */ iLen = GetDlgItemText(hwnd, ID_COMMAND, szBuffer, MAX_COMMAND); SendTextToEditControl (szBuffer); /* Send command to WorldView */ DdeClientTransaction(szBuffer, strlen(szBuffer)+1, hConversation, NULL, CF_TEXT, XTYP_EXECUTE, 10000, &dwResult); /* Get result from WorldView */ hResult = DdeClientTransaction(NULL, 0, hConversation, hszResult, CF_TEXT, XTYP_REQUEST, 10000, &dwResult); if(hResult != (HDDEDATA)NULL) { char FAR * szResult = DdeAccessData(hResult, NULL); SendTextToEditControl(szResult); DdeUnaccessData(hResult); } SendMessage (GetDlgItem (hwndMain, ID_COMMAND), EM_SETSEL, 0, MAKELONG (-1, -1)); SetFocus(GetDlgItem(hwnd, ID_COMMAND)); return(0); case ID_COMMAND : return(0); case ID_RESULT : return(0); } case WM_SETFOCUS : SetFocus(GetDlgItem(hwnd, ID_COMMAND)); return(0); case WM_DESTROY : PostQuitMessage(0); return(0); } return(DefWindowProc(hwnd, message, wParam, lParam)); } /* If the message involves the ENTER key, we execute the command; otherwise pass it on to the normal edit procedure */ LRESULT FAR PASCAL EditProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_KEYDOWN : if(wParam == VK_RETURN) { PostMessage(hwndMain, WM_COMMAND, ID_EXECUTE, 0L); return(0); } case WM_KEYUP : case WM_CHAR : if(wParam == VK_RETURN) return(0); } return(CallWindowProc(lpfnOldEditProc, hwnd, message, wParam, lParam)); }