Jak odeslat výsledek do jiného okna? – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Jak odeslat výsledek do jiného okna? – C / C++ – Fórum – Programujte.comJak odeslat výsledek do jiného okna? – C / C++ – Fórum – Programujte.com

 

oxidián0
Grafoman
5. 9. 2015   #1
-
0
-

V programu mám dvě okna, hlavní okno obsahující formulář (model editunits.cpp) a okno prohlížeče (Map Viewer - mapviewer.cpp). Jsou to samostatné moduly které mají každý svůj dlgproc. Když kliknu na mapu, posílám zprávu do okna mapviewer abych zavolal funkci pro přepočet souřadnic (rotace součadnic). Výslednou hodnotu potřebuju dostat zpět do původního okna editunits abych mohl pokračovat ve zpracování.

mapviewer.cpp

LRESULT CALLBACK MapWndProc(HWND window, UINT msg, WPARAM wParam, LPARAM lParam)
{
    LRESULT ret = 0;
    int i;

    switch (msg)
    {
        ...
    case MAP_RotateCoords:
        RotateCoords(window, wParam, lParam);
        break;
    default:
        ret = DefWindowProc(window, msg, wParam, lParam);
    }
    return ret;
}        

editunits.cpp:

void Units_HandleMapClick(HWND dialog, int x, int y)
{
...
SendMessage(dialog, MAP_RotateCoords, x, y);
// Sem potřebuju dát výsledek z fuknce RotateCoords..
SetDlgItemFloat(dialog, IDC_U_X, x + 0.5);
SetDlgItemFloat(dialog, IDC_U_Y, y + 0.5);
Units_Save(dialog);
SendMessage(mv, MAP_HighlightPoint, x, y);
SendMessage(mv, MAP_Reset, 0, 0);
}

funkce v mapviewer.cpp:

void RotateCoords(HWND window, int x, int y)
{
  if (x < 0 || x > SHRT_MAX ||
    y < 0 || y > SHRT_MAX)
    return;

  int rx, ry;
  unsigned int urx, ury; // (unsigned)
  int half = data.scen->map.x / 2;
        
  if (setts.view.rotation_0)
    rotate(half, (int)iter->x, (int)iter->y, rx, ry);
    else
  if (setts.view.rotation_315)
    {
    unrotate(data.scen->map.x, (int)iter->x, (int)iter->y, urx, ury);
    rx=urx;
    ry=ury;
    }
  else
  if (setts.view.rotation_45)
    { // no rotate
     rx = (int)iter->x * setts.zoom * 2;
         ry = (data.scen->map.y - (int)iter->y * setts.zoom)*2;
    }
}

rx a ry jsou rotované souřadnice  a chci je poslat z okna mapviewer do hlavního okna (editunits module).

Jak to udělat?

editunits.cpp dlgproc http://paste.ofcode.org/Jxzpyp9wEpiEyp5mJZHMtE

Nahlásit jako SPAM
IP: 78.45.87.–
ondrej39+1
Věrný člen
5. 9. 2015   #2
-
0
-

#1 oxidián
Změň si návratový typ z void na strukturu zabalující ty dva body a v místě, kde v hlavním okně tu funkci voláš, si výsledek funkce prostě přiřaď do té struktury a tu strukturu použij.

Edit: Sorry, nevšiml jsem si, že mapviewer.cpp je asi součástí nějaké knihovny, kterou si stáhl a neměl bys upravovat. Tak si na funkci RotateCoords napiš fasádu, která ti tu strukturu vrátí, a tu logiku si prostě budeš muset udělat v ní.

Nahlásit jako SPAM
IP: 46.39.172.–
Inject all the dependencies!
oxidián0
Grafoman
5. 9. 2015   #3
-
0
-

#2 ondrej39
Ne, v pohodě, mohu to upravovat, je to vše jeden program.

Nahlásit jako SPAM
IP: 78.45.87.–
Radek Chalupa
~ Redaktor
+1
Super člen
5. 9. 2015   #4
-
0
-

#3 oxidián
V zásadě všechno můžeš předávat přes uživatelské zprávy, pokud je to v rámci procesu, pak lparam může obsahovat pointer na libovolné velkou datovou strukturu, kterou s ijen přetypuješ "tam a zpátky"; A pokud by to bylo mezi procesy které nemájí společnou paměť, tak lze použít zprávu WM_COPYDATA, kde se o zkopírování z jednpoho paměťového prostoru do druhého postará systém.

Radek Chalupa
- individuální konzultace, školení programování (C/C++, WinAPI, COM, ActiveX, ATL, C#, NET Framework, MFC)
- vývoj software na zakázku
http://www.radekchalupa.cz

Nahlásit jako SPAM
IP: 89.177.51.–
oxidián0
Grafoman
5. 9. 2015   #5
-
0
-

ondrej39: Dobrej tip, ale myslel si asi vrátit odkaz na strukturu, správně?

Nahlásit jako SPAM
IP: 78.45.87.–
Radek Chalupa
~ Redaktor
+1
Super člen
5. 9. 2015   #6
-
0
-

#5 oxidián
Ano, myslel jsem jako lparam zprávy zadat odkaz/ukazatel/pointr na požadovanou strukturu. Je to rychlejší než předávání hodnotou (samozřejmě u významě velkého objemu dat) - při předání ukazatelem se zkopíruje pouze 4 nebo 8 (podle platformy - 32 vs 64-bit) bytů.

Radek Chalupa
- individuální konzultace, školení programování (C/C++, WinAPI, COM, ActiveX, ATL, C#, NET Framework, MFC)
- vývoj software na zakázku
http://www.radekchalupa.cz

Nahlásit jako SPAM
IP: 89.177.51.–
oxidián0
Grafoman
5. 9. 2015   #7
-
0
-

Z MSDN: SendMessage function

"Type: LRESULT

The return value specifies the result of the message processing; it depends on the message sent."

Takže tam nemusí být jen odkaz, ale může tam být vrácena i ta struktura? Já až doposavad nechápal  co přesně to LRESULT znamená. Ale RESULT nám asi říká že tam může být jakýkoliv výsledek z funkce, pak co znamená to L?

Nahlásit jako SPAM
IP: 78.45.87.–
Radek Chalupa
~ Redaktor
+1
Super člen
5. 9. 2015   #8
-
0
-

#7 oxidián
Nikoliv LRESULT ale LPARAM (jak jsem psal), tj. čtvrtý parametr funkce SendMessage a procedury okna!!!

Radek Chalupa
- individuální konzultace, školení programování (C/C++, WinAPI, COM, ActiveX, ATL, C#, NET Framework, MFC)
- vývoj software na zakázku
http://www.radekchalupa.cz

Nahlásit jako SPAM
IP: 89.177.51.–
ondrej39+1
Věrný člen
5. 9. 2015   #9
-
0
-

#5 oxidián
Jo, jasně, prostě abys ta data ven z funkce dostal :).

Nahlásit jako SPAM
IP: 46.39.172.–
Inject all the dependencies!
oxidián0
Grafoman
6. 9. 2015   #10
-
0
-

Aktuálně zkouším nejdříve vrátit strukturu:

typedef struct COORDS_STRUCT {
    int x;
    int y;
} COORDS;

COORDS coords;

...

coords = SendMessage(dialog, MAP_RotateCoords, x, y);

vrací chybu:

error C2679: binary '=' : no operator found which takes a right-hand operand of type 'LRESULT' (or there is no acceptable conversion)
1>          i:\c++ vs sources\aokts-1.0.1 r72c update_test\model\map_viewer.h(69): could be 'COORDS_STRUCT &COORDS_STRUCT::operator =(const COORDS_STRUCT &)'
1>          while trying to match the argument list '(COORDS, LRESULT)'

Přes pointer jsem to zatím nezkoušel

Nahlásit jako SPAM
IP: 78.45.87.–
ondrej39+1
Věrný člen
6. 9. 2015   #11
-
0
-

#10 oxidián

V C++ nemusíš psát typedef struct.

Ten error máš proto, protože ti chybí přetížení přiřazovacího (=) operátoru, máš strukturu coords, což je proměnná typu COORDS, a snažíš se do ní přiřadit výsledek funkce SendMessage, funkce, která vrací LRESULT.

struct COORDS
{
    int x;
    int y;

    COORDS& operator=(LRESULT&& lResult)
    {
        // něco s lResult
        return *this;
    }
};

To, co chceš, jsem v C++ nedělal, ale jestli potřebuješ hlavnímu oknu před zprávu přes ten LRESULT a do LlRESULT se dá nějakým způsobem narvat odkaz (nevím, co je LRESULT, není to nějaký void pointer?) na tebou vytvořenou strukturu, tak to udělej tak.

Nahlásit jako SPAM
IP: 46.39.172.–
Inject all the dependencies!
oxidián0
Grafoman
6. 9. 2015   #12
-
0
-

Stále to nechápu, zkouším to takhle:

Shared struct:

typedef struct COORDS_STRUCT {
	int x;
	int y;
} COORDS, *PCOORDS;

mapview.cpp:

COORDS coords;


vytvořím tu strukturu do které se budou ukládat ty souřadnice. V tom samém souboru mám nadefinovanou funkci - (chaos v pointerech a return typech:

PCOORDS RotateCoords(HWND window, int x, int y)
{
  if (x < 0 || x > SHRT_MAX ||
		y < 0 || y > SHRT_MAX)
	{  coords.x=-1; coords.y=-1;
		return coords;
	}
		

  unsigned int urx, ury; // (unsigned)
	int half = data.scen->map.x / 2;
		
  if (setts.view.rotation_0)
    rotate(half, x, y, coords.x, coords.y);
	else 
  if (setts.view.rotation_315)
    // unrotate(data.scen->map.x / 2, x, y, rx, ry); // rx = coords.x
    {
    unrotate(data.scen->map.x, x, y, urx, ury);
    coords.x = urx;
    coords.y = ury;
    }
  else
  if (setts.view.rotation_45)
    { // no rotate 
     coords.x = x * setts.zoom * 2;
		 coords.y = (data.scen->map.y - y * setts.zoom)*2;
    }
  return *coords;  
}

Jak mám vrátit ten pointer na strukturu?

No kdybych to udělal takto:

PCOORDS RotateCoords(HWND window, int x, int y)
{

COORDS coords;

COORDS * pcoords;

...

return pcoords;

}

Tak to krachne ne? Protože v době kdy budu vracet pointer na coords už ta struktura nebude existovat, jelikož lokální proměnná zaniká po ukončení volání funkce.

Připomínám že v unitsedit.cpp budu mít toto:

PCOORDS * pcoords;

pcoords = SendMessage(dialog, MAP_RotateCoords, x, y);


Což má zavolat tu funkci RotateCoords a vrátit odkaz

Edit:

Taky dostávám hlášku:

unitsedit.cpp: error C2440: '=' : cannot convert from 'LRESULT' to 'PCOORDS *'

pcoords = SendMessage(dialog, MAP_RotateCoords, x, y);
Nahlásit jako SPAM
IP: 78.45.87.–
ondrej39+1
Věrný člen
6. 9. 2015   #13
-
0
-

#12 oxidián
Kompiluješ v C++11? Pokud ano, na pointer bych se upřímně vyprdnul, vrátil bych si strukturu jako hodnotu a přes std::move si obsah vrácené hodnoty nabouchal do vytvořené proměnné o scope výš, aby se to zbytečně nekopírovalo a jenom si přesunul referenci.

Nicméně, i když si vyřešíš, jak získat tu strukturu z funkce RotateCoords, neřeší ti to problém, kdy musíš ještě dostat z tohoto okna do okna jiného (a pokud ti funkce, která spravuje jedno okno vrací LRESULT, budeš si muset najít způsob, jak tu svou strukturu do toho callbacku nějakým způsobem namapovat).

Nahlásit jako SPAM
IP: 46.39.172.–
Inject all the dependencies!
oxidián0
Grafoman
6. 9. 2015   #14
-
0
-

Visual Studio 2010 nepodporuje C++11

Nahlásit jako SPAM
IP: 78.45.87.–
ondrej39+1
Věrný člen
6. 9. 2015   #15
-
0
-

#14 oxidián
Pokud jediný důvod, proč neprogramuješ v C++11 je, že ti ho nepodporuje IDE, tak doporučuji přejít na IDE, který C++11 přežvejká. Doby, kdys musel v C++ manuálně uvolňovat paměť jsou už pryč.

Nahlásit jako SPAM
IP: 46.39.172.–
Inject all the dependencies!
oxidián0
Grafoman
6. 9. 2015   #16
-
0
-

Skoro to mám

Ale proč se děje toto ?

Ve sdíleném souboru mám:

typedef struct COORDS_STRUCT {
    int x;
    int y;
} COORDS, *PCOORDS;
PCOORDS pcoords;

pcoords má být použit ve vícero cpp spouborech abych získal LRESULT z SendMessage.

V souboru cpp  kde jsem definoval funkci nejdříve vytvořím instanci coords a pak chci vytvořit pointer na coords:

COORDS coords;
pcoords = &coords; // used to return coords from SendMessage call to mapview.cpp
 

error missing declaration for pcoords (ale ten soubor se sdílenými daty jsem už nainkludoval).... a dále

COORDS coords;
PCOORDS pcoords = &coords; // used to return coords from SendMessage call to mapview.cpp

error C2086: 'PCOORDS pcoords' : redefinition ...

Tak jak to vyřešit?

Nahlásit jako SPAM
IP: 78.45.87.–
ondrej39+1
Věrný člen
6. 9. 2015   #17
-
0
-

#16 oxidián
Dej si do toho souboru, kterej sdíleně includuješ, header guard pro překladač.

#ifndef SHARED_LIBRARIES_H
#define SHARED_LIBRARIES_H

// Sem dej všechen kód

#endif

Pak si to můžeš includovat jak chceš, klidně 10x po sobě, ale vždycky to určitě budeš mít naincludované jenom jednou a k redefinici nikdy nedojde. Pokud ti deklarace chybí, tak jsi naincludoval ten soubor špatně.

Jinak ta Maďarská notace už je taky pěkně zastaralá. Na to máš dneska právě IDE, abys zjistil, co ti co vrací. Akorát si tak prodlužuješ názvy proměnných a tříd. A mám takový trošku dojem, že ten kód plácáš pátý přes devátý a objekty, ta výborná věc, kterou nejen C++ má, tě moc nezajímají.

Nahlásit jako SPAM
IP: 79.141.243.–
Inject all the dependencies!
oxidián0
Grafoman
6. 9. 2015   #18
-
0
-

Ale to tam mám ten header guard.

TOTO JE TEN PROBLÉM:  

SOUBOR.CPP

pcoords = &coords;

 error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

error C2040: 'pcoords' : 'int' differs in levels of indirection from 'PCOORDS'
error C2440: 'initializing' : cannot convert from 'COORDS *' to 'int'
1>          There is no context in which this conversion is possible

POČKAT:

Takže to mám posunout celé do headeru? Včetně vytvoření instance uvnitř headeru?

COORDS coords;
PCOORDS pcoords = &coords;

ALE:

I když tu deklaraci přesunu do headeru, tak to stále píše že je tam ta redifinice.

Navíc ten header se inkluduje asi na 10 místech takže teď to hází chybu redefinice 10x

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
6. 9. 2015   #19
-
0
-

Je to v háji. Mám to skoro vyřešené, ale zase v souboru editunits.cpp mám link error

 error LNK2005: "struct COORDS_STRUCT * pcoords" (?pcoords@@3PAUCOORDS_STRUCT@@A) already defined in editunits.obj
1>.\aokts.exe : fatal error LNK1169: one or more multiply defined symbols found

to už jsem odstranil z té sdílené části PCOORDS pcoords; a dal jsem to do dvou cpp souborů
 

Nahlásit jako SPAM
IP: 78.45.87.–
KIIV
~ Moderátor
+43
God of flame
6. 9. 2015   #20
-
0
-

A ted je zase na case naucit se kouzelne slovo "extern"

Nahlásit jako SPAM
IP: 94.113.92.–
Program vždy dělá to co naprogramujete, ne to co chcete...
ondrej39+1
Věrný člen
6. 9. 2015   #21
-
0
-

#19 oxidián
Mít deklaraci proměnné v tom sdíleném headeru smrdí globální proměnnou a to rozhodně nechceš. V tom headeru máš mít jen deklaraci (případnou definici nějakých metod) té struktury, nemáš v něm vytvářet žádnou proměnnou typu COORDS ani PCOORDS.

Ten error linkeru ti předpokládám vznikl proto, protože deklaruješ strukturu třeba s názvem coords v tom sdíleném headeru a pak deklaruješ strukturu se stejným názvem i v jiném souboru, třeba uvnitř nějaké metody. Logicky, pokud máš tu v tom sdíleném headeru globální, tak linker pak neví, jaká proměnná je ta správná.

Během vývoje ti to nebude vypisovat real-time chyby, ale při kompilaci to prostě chcípne.

Nahlásit jako SPAM
IP: 79.141.243.–
Inject all the dependencies!
oxidián0
Grafoman
7. 9. 2015   #22
-
0
-

Dobrá, díky za vysvětlení. Takže pokud to chápu shrnu to takto:

- ve síleném headeru pouze nadeklarovat strukturu COORDS a pointer na strukturu PCOORDS, nevytvářet žádné proměnné

- v headerech příslušných modulů deklarovat extern COORDS coords; extern PCOORDS pcoords;

- v souborech cpp příslušných modulů nastavit příslušné hodnoty proměnným; PCOORDS pcoords = &coords; a coords nastavím přes tu funkci.

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
7. 9. 2015   #23
-
0
-

A souboru cpp:

extern struct COORDS coords;
extern struct PCOORDS pcoords;
pcoords = (PCOORDS) SendMessage(dialog, MAP_RotateCoords, x, y);

mám tyto chyby:

error C2582: 'operator =' function is unavailable in 'PCOORDS'
error C2146: syntax error : missing ';' before identifier 'SendMessageA'

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
7. 9. 2015   #24
-
0
-

Proč mi prostě nenapíšete jak to mám napsat.

Kde teda mám dát ten extern? Dal jsem ho do té sdílené deklarace:

extern struct COORDS_STRUCT {
    int x;
    int y;
} COORDS, *PCOORDS;

A co mám teda napsat do těch dalších souborů aby to neházelo pořád nějaký chyby?

Nahlásit jako SPAM
IP: 78.45.87.–
ondrej39+1
Věrný člen
7. 9. 2015   #25
-
0
-

#23 oxidián
Ti to kompilátor všechno píše. Chybí ti přetížení assignment operátoru...

COORDS& operator=(const COORDS& other)
{
    // tady něco jako this->x = other.x; this->y = other.y
}

Nejsem si teda úplně jistej, co ti udělá přetypování LRESULTu na PCOORDS, zda to vůbec můžeš udělat.

Nahlásit jako SPAM
IP: 78.156.159.–
Inject all the dependencies!
oxidián0
Grafoman
7. 9. 2015   #26
-
0
-

#25 ondrej39
Tam není COORDS ale PCOORDS, tedy pointer na strukturu. Jak chceš přetížit pointer? Prostě potřebuju vrátit odkaz na strukturu a uložit to do pcoords. Nechápu proč píše tuto hlášku? Jako že pointer nelze nastavit? Proč?

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
7. 9. 2015   #27
-
0
-

A když napíšu do cpp toto:

COORDS coords;
extern struct PCOORDS pcoords = &coords;

tak dostanu chybu

error C2146: syntax error : missing ';' before identifier 'coords'
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
error C2371: 'COORDS' : redefinition; different basic types

A když tam nechám pouze toto:

extern struct PCOORDS pcoords = &coords;

tak dostanu chybu

error C2065: 'coords' : undeclared identifier
error C2514: 'PCOORDS' : class has no constructors


Prostě já už fakt nevím co s tím, už jsem zkusil tolik možností...

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
7. 9. 2015   #28
-
0
-

už to mám opravené, takže zkompilováno

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
7. 9. 2015   #29
-
0
-

No a teď se chci zeptat, když tedy odešlu tu zprávu

pcoords = (PCOORDS) SendMessage(dialog, MAP_RotateCoords, x, y);

potřebuju počkat až okno dialog obdrží tu zprávu a spustí tu funkci, aby souřadnice ve stukruře coords byly nově nastaveny. Jak to tedy udělat? Nyní mám výsledek coords.x==0 a coords.y==0 a domnívám se že je to tím, že se ta zpráva ještě nezpracovala. mám tam totiž break point přímo v té funkci RotateCoords a nic se nestalo. A pro jistotu jsem dal break point i do toho zachytávače zpráv.

Nahlásit jako SPAM
IP: 78.45.87.–
ondrej39+1
Věrný člen
7. 9. 2015   #30
-
0
-

#29 oxidián
To je divný. Z MSDN: Sends the specified message to a window or windows. The SendMessage function calls the window procedure for the specified window and does not return until the window procedure has processed the message.

Určitě v té struktuře, kterou chceš jako callback, jsou data?

Nahlásit jako SPAM
IP: 79.141.243.–
Inject all the dependencies!
oxidián0
Grafoman
7. 9. 2015   #31
-
0
-

O to přece nejde jestli tam jsou data, ona nemusí být iniciovaná. Spíš ten problém vidím v tom, že debugger neskočí na ten řádek kde se ta zpráva zpracovává. Budu se muset podívat jestli tam nemám špatný WHND. Já tu aplikaci celou nepsal, takže je možné že mi něco uniklo.

Nahlásit jako SPAM
IP: 78.45.87.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 43 hostů

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý