c + + - Passerer en peger til en lokal variabel til en anden proces fungerer nogle gange og ikke andre

Indlæg af Hanne Mølgaard Plasc

Problem



Et stykke tid siden skrev jeg et program, der lader dig vælge og ændre vinduer. Det bruger WindowFromPoint() for at få et håndtag til vinduet under musemarkøren og kalder GetWindowText() på det for at få vinduets titel. Det virker fint.


Jeg tilføjede derefter evnen til at få titlen på kolonner af en listekontrol. Problemet er, at i modsætning til GetColumnWidth(), som returnerer bredden, er der ingen tilsvarende funktion for at få titlen. I stedet for at få titlen på kolonneoverskriften kræver en buffer til GetColumn() for at udfylde titlen. Som sådan, når jeg tildeler pszText medlemmet af en LVCOLUMN struktur til en peger til en buffer og sender strukturen til GetColumn(), tolker den anden proces markøren som inden for sit eget hukommelsesrum . Det vil naturligvis ikke fungere.


Jeg arbejdede rundt ved at bruge en metode fra en CodeProject-artikel. Det fungerede godt. Men jeg er stadig forvirret over hvorfor GetWindowText() gjorde arbejde. [17]


Det er forvirrende, fordi GetWindowText() fungerer det samme som GetColumn(); det returnerer ikke vinduetitel, det tager en buffer/variabel for at sætte titlen i.


Så hvorfor passerer en variabel til en anden proces, der skal udfyldes, arbejde i et scenarie, men ikke en anden?





Her er et uddrag, der får vinduetitel:


// m\_Wnd is a pointer to a window class, pointing to a window in another process
CWnd *m\_Wnd=WindowFromPoint(point);

// t is a local variable within this program’s address space
CString t;

// passing a reference to a local variable to another process
m\_Wnd->GetWindowText(t); //works correctly!




Her er et tilsvarende uddrag for at få titlen på en kolonne:


// *lc points to a list-control in another process
int         colwidth = lc->GetColumnWidth(col); //works correctly!

// local variables
CString     colname  = \_T("");
LVCOLUMN    col;
memset(&col, 0, sizeof(col));

col.mask=LVCF\_TEXT;
col.cchTextMax=256;
col.pszText=colname.GetBuffer(256);  // passing a pointer to local buffer
BOOL ret=lc.GetColumn(colnum, &col); // buffer is empty
colname.ReleaseBuffer();

Bedste reference


GetWindowText er speciel. Når du kalder det på et vindue, der tilhører en anden proces, kalder det faktisk ikke den anden proces for at få teksten. [18]


CListCtrl::GetColumn på den anden side er en inline-funktion (se afxcmn.inl), der kalder SendMessage, så meddelelsen går til den anden proces, som derefter fortolker markøren i sit eget hukommelsesrum.

Andre referencer 1


Dette er ikke et svar, men et forslag ... Det kan være, at det andet vindue er Unicode. I så fald skal du muligvis bruge wice-tegnversionerne til at få det til at fungere. Der er en API funktion IsWindowUnicode (), som vil fortælle dig om et givet vindue er native Unicode.