[ passwdpasswd @ 02.11.2006. 19:10 ] @
DDE [Dynamic Data Exchange] Opcenito vidim da na netu ima jako slabo materijala sto se tice samog DDE-a i DDE optimizacije kod raznih softwareskih paketa (osim MSDN-a), pa evo ako ce nekom trebat?? Neda mi se o njemu pricat... uglavnom postoje 3 vrste veza: 1. hot link-vruca veza 2. warm link-topla veza 3. cold link-hladna veza DDE se moze koristit preko samog win32apija ili pak preko DDEML-a (Dynamic Data Exchange Managment Library) Ovdje cu napravit primjer hot linka bez azuriranja podataka preko apija, kod je iskompajliran u Dev-C++ 4.9.9.2! Znaci ovo je DDE server: Code: #include <windows.h> #include <dde.h> /* Declare Windows procedure */ LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM); /* Make the class name into a global variable */ char szClassName[ ] = "WindowsApp"; BOOL ProvjeriDalGaIma(char szBr[100]) { BOOL nadjen=FALSE; char brojevi[11][10] = {"nula","jedan","dva","tri","cetri","pet","sest","sedam", "osam","devet","deset"}; for (int x=0;x<=10;x++) if (strcmp(brojevi[x],szBr)==0) nadjen=TRUE; if (nadjen==TRUE) return TRUE; else return FALSE; } int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nFunsterStil) { HWND hwnd; /* This is the handle for our window */ MSG messages; /* Here messages to the application are saved */ WNDCLASSEX wincl; /* Data structure for the windowclass */ /* The Window structure */ wincl.hInstance = hThisInstance; wincl.lpszClassName = szClassName; wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */ wincl.style = CS_DBLCLKS; /* Catch double-clicks */ wincl.cbSize = sizeof (WNDCLASSEX); /* Use default icon and mouse-pointer */ wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION); wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION); wincl.hCursor = LoadCursor (NULL, IDC_ARROW); wincl.lpszMenuName = NULL; /* No menu */ wincl.cbClsExtra = 0; /* No extra bytes after the window class */ wincl.cbWndExtra = 0; /* structure or the window instance */ /* Use Windows's default color as the background of the window */ wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND; /* Register the window class, and if it fails quit the program */ if (!RegisterClassEx (&wincl)) return 0; /* The class is registered, let's create the program*/ hwnd = CreateWindowEx ( 0, /* Extended possibilites for variation */ szClassName, /* Classname */ "Windows App", /* Title Text */ WS_OVERLAPPEDWINDOW, /* default window */ CW_USEDEFAULT, /* Windows decides the position */ CW_USEDEFAULT, /* where the window ends up on the screen */ 544, /* The programs width */ 375, /* and height in pixels */ HWND_DESKTOP, /* The window is a child-window to desktop */ NULL, /* No menu */ hThisInstance, /* Program Instance handler */ NULL /* No Window Creation data */ ); /* Make the window visible on the screen */ ShowWindow (hwnd, nFunsterStil); /* Run the message loop. It will run until GetMessage() returns 0 */ while (GetMessage (&messages, NULL, 0, 0)) { /* Translate virtual-key messages into character messages */ TranslateMessage(&messages); /* Send message to WindowProcedure */ DispatchMessage(&messages); } /* The program return-value is 0 - The value that PostQuitMessage() gave */ return messages.wParam; } /* This function is called by the Windows function DispatchMessage() */ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { ATOM aApp, aTopic, aItem, aRecvItem, aSentItem; UINT uiLow, uiHi; GLOBALHANDLE hDdeAdvise, hDdeData; DDEADVISE *pDdeAdvise; DDEDATA *pDdeData; DDEACK DdeAck; WORD wStatus; char RecvBuff[100], SendBuff[10]; switch (message) /* handle the messages */ { case WM_DDE_INITIATE: aApp=GlobalAddAtom("generator"); aTopic=GlobalAddAtom("brojevi"); if (LOWORD(lParam)==aApp && HIWORD(lParam)==aTopic) SendMessage((HWND)wParam, WM_DDE_ACK, (WPARAM)hwnd, MAKELPARAM(aApp, aTopic)); else{GlobalDeleteAtom(aApp); GlobalDeleteAtom(aTopic);} break; case WM_DDE_ADVISE: UnpackDDElParam(WM_DDE_ADVISE, lParam, &uiLow, &uiHi); FreeDDElParam(WM_DDE_ADVISE, lParam); hDdeAdvise=(GLOBALHANDLE) uiLow; pDdeAdvise=(DDEADVISE *) GlobalLock(hDdeAdvise); aRecvItem=(ATOM)uiHi; GlobalGetAtomName(aRecvItem, RecvBuff, sizeof(RecvBuff)); if (ProvjeriDalGaIma(RecvBuff)==TRUE) { if (strcmp(RecvBuff,"nula")==0) strcpy(SendBuff,"0"); if (strcmp(RecvBuff,"jedan")==0) strcpy(SendBuff,"1"); if (strcmp(RecvBuff,"dva")==0) strcpy(SendBuff,"2"); if (strcmp(RecvBuff,"tri")==0) strcpy(SendBuff,"3"); if (strcmp(RecvBuff,"cetiri")==0) strcpy(SendBuff,"4"); if (strcmp(RecvBuff,"pet")==0) strcpy(SendBuff,"5"); if (strcmp(RecvBuff,"sest")==0) strcpy(SendBuff,"6"); if (strcmp(RecvBuff,"sedam")==0) strcpy(SendBuff,"7"); if (strcmp(RecvBuff,"osam")==0) strcpy(SendBuff,"8"); if (strcmp(RecvBuff,"devet")==0) strcpy(SendBuff,"9"); if (strcmp(RecvBuff,"deset")==0) strcpy(SendBuff,"10"); //saljemo WM_DDE_DATA hDdeData=(GLOBALHANDLE) GlobalAlloc(GHND | GMEM_DDESHARE, sizeof(DDEDATA)+strlen(SendBuff)); pDdeData=(DDEDATA *) GlobalLock(hDdeData); pDdeData->cfFormat=CF_TEXT; if (pDdeAdvise->fAckReq==TRUE) pDdeData->fAckReq=TRUE; else pDdeData->fAckReq=FALSE; pDdeData->fResponse=FALSE; pDdeData->fRelease=TRUE; lstrcpy((PSTR)pDdeData->Value, SendBuff); GlobalUnlock(hDdeData); PostMessage((HWND)wParam, WM_DDE_DATA, (WPARAM)hwnd, PackDDElParam(WM_DDE_DATA, (UINT)hDdeData, aRecvItem)); GlobalFree(hDdeData); } else { //saljemo WM_DDE_ACK jer nemamo trazeni podatak DdeAck.bAppReturnCode=0; DdeAck.reserved=0; DdeAck.fAck=FALSE; DdeAck.fBusy=FALSE; wStatus=*((WORD *)&DdeAck); PostMessage((HWND)wParam, WM_DDE_ACK, (WPARAM)hwnd, PackDDElParam(WM_DDE_ACK, wStatus, aRecvItem)); } GlobalUnlock(hDdeAdvise); GlobalFree(hDdeAdvise); break; case WM_DDE_UNADVISE: aItem=HIWORD(lParam); DdeAck.bAppReturnCode=0; DdeAck.reserved=0; DdeAck.fAck=FALSE; DdeAck.fBusy=FALSE; wStatus=*((WORD *)&DdeAck); PostMessage((HWND)wParam, WM_DDE_ACK, (WPARAM)hwnd, PackDDElParam(WM_DDE_ACK, wStatus, aItem)); break; case WM_DDE_TERMINATE: PostMessage((HWND)wParam, WM_DDE_TERMINATE, (WPARAM)hwnd, 0L); break; case WM_DESTROY: PostQuitMessage (0); /* send a WM_QUIT to the message queue */ break; default: /* for messages that we don't deal with */ return DefWindowProc (hwnd, message, wParam, lParam); } return 0; } Jedan od DDE klijent programa je i MS Excel, naime svaka DDE komunikacija se sastoji od 3 elementa: aplikacija, predmet i element! U ovom gore slucaju aplikacija se zove generator, predmet se zove brojevi a elementi su brojevi [nula, jedan, dva.... deset], znaci ako u MS Excel celiji ukucate "=generator|brojevi!jedan" (bez navodnika) i lupite enter u celiji ce se pojavit broj 1, ako napisete =generator|brojevi!osam u celiji ce se pojavit broj 8, naime onaj nas DDE server pretvara brojeve pisane slovima u brojke!! Naravno DDE server mora bit upaljen u to vrijeme, evo slika kako to izgleda: U attachu imate iskompajliran kod! z [Ovu poruku je menjao passwdpasswd dana 02.11.2006. u 20:23 GMT+1] |