Zdravím,
mohl by sem někdo prosím vložit kód, který vytvoří nové okno? Fce. CreateWindow z WinAPI - stačí to nejjednodušší řešení + potřebuji vědět handle tohoto okna. Rád bych si něco vyzkoušel. Díky.
Díky, tak okno nové aplikace už mám. Teď si pohrávám s myšlenkou, jestli by šlo doplnit kod, který by mi zapsal nějaký text do okna, které patří jiné aplikaci, když znám handle toho okna. Za prvé - jde to vůbec? Pokud ano - jak na to (pokud to není nějaké hardcore kodování)? Díky.
#3 end
Samozřejmě že to jde:
SendMessage(handle_okna, WM_SETTEXT, 0, (LPARAM)L"Nějaký text");
Jenom si musíš být jistý že ten handle je v daném okamžiku platný a je to (v většině případů) přímo handle nějakého vnořeného prvku (asi edit control) a nikoliv hlavní okno té aplikace.
Radek Chalupa
- vývoj software na zakázku
- školení programování (C/C++, WinAPI, ATL, COM, ActiveX, C#, NET Framework, MFC)
http://www.radekchalupa.cz
#5 end
Psal jsi že to okno patří jiné aplikaci, tak jak můžeš mít handle z volání CreateWindow?
Chyba může být kdekoliv, nejspíš v získání handle, nebo je to okno typu který text přímo nezobrazuje, i když ho lze nastavit (např. listbox). Když sem dáš příslušný kus zdrojáku, možná se na chybu přijde...
Radek Chalupa
- vývoj software na zakázku
- školení programování (C/C++, WinAPI, ATL, COM, ActiveX, C#, NET Framework, MFC)
http://www.radekchalupa.cz
#6 Radek Chalupa
Tak vložím kod - udělá jen nové konzolové okno aplikace: Handle toho okna beru jako hwnd = CreateWindowEx (..). Jestli je tohle špatně? A čeho chci dosáhnout je zapsat do tohoto okna nějaký text, ale ne z tohoto kodu, ale z jiné aplikace, takže s využitím nějaké fce. WinApi. To mi tedy nejde. Děkuji.
Pokud by bylo jednodušší - tak bych si i vystačil s novým oknem (nemuselo by jít o konzolovou aplikaci, stačí jen samotné okno) a do něj pak posílat nějaký text z jiné aplikace. Ale to okno asi musí někam patřit (hierarchicky), no nebudu to komplikovat nebo se do toho zamotám...
#include <windows.h>
/* Declare Windows procedure */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
/* Make the class name into a global variable */
char szClassName[ ] = "WindowsApp";
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 */
250, /* 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);
/* 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)
{
switch (message) /* handle the messages */
{
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;
}
#7 end
Ten zdroják je jen vytvoření cílového okna, v tom problém nebude....
Nicméně, tady je ukázka jak nastavit v (před tím samozřejmě spuštěném) notepadu jak text v titulku, tak přímo v tom editačním okně:
BOOL CALLBACK enum_child_proc(HWND hwnd, LPARAM lparam)
{
wchar_t sz_class[50];
GetClassName(hwnd, sz_class, sizeof(sz_class)/sizeof(wchar_t));
if (lstrcmpi(sz_class, L"edit") == 0)
{
SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)L"Text v okně editu");
return FALSE;
}
else
return TRUE;
}
void test()
{
HWND h = FindWindow(L"Notepad", NULL);
if (IsWindow(h))
SendMessage(h, WM_SETTEXT, 0, (LPARAM)L"Text v titulku");
EnumChildWindows(h, enum_child_proc, 0);
}
Radek Chalupa
- vývoj software na zakázku
- školení programování (C/C++, WinAPI, ATL, COM, ActiveX, C#, NET Framework, MFC)
http://www.radekchalupa.cz
#8 Radek Chalupa
Nevím, jestli jsem to udělal správně - jsem to přidal ke stávajícímu kodu a zavolal jsem si fci test(), ale překladač vyhodil celou řadu hlášek, viz. screen :-(
ta hláška Illegal byte sequence se týká zápisu: if (lstrcmpi(sz_class, L"edit") == 0)Připojen obrázek.
#9 end
Znamená to že máš nastavenou kompilaci pro ANSI znakovou sadu. Doporučuji používat Unicode, to už je v MS Visual C++ jako výchozí minimálně od verze 2008. Jinak můžeš ve zdrojáku používat "univerzální" TCHAR všude místo wchar_t a v textových konstantách místo L používat makro TEXT nebo _T, tj. TEXT("něco"), nebo _T("něco").
Radek Chalupa
- vývoj software na zakázku
- školení programování (C/C++, WinAPI, ATL, COM, ActiveX, C#, NET Framework, MFC)
http://www.radekchalupa.cz
#11 end
Ještě se zeptám - lehce odbočím - lze vytvořit samotné okno (s úspornějším kodem než jsem uvedl, nemusí to být konsolová aplikace) - "nic" od něj nečekám, jenom jeho existenci, možnost minimalizace, zavření, nastavit umístění, velikost, aby bylo vždy navrchu a možnost do něj z jiné aplikace posílat informační text?
#11 end
To makro je v hlavičkovém souboru (jestli se nepletu tchar.h) který nemáš includovaný ve zdrojáku. Jinak ale opravdu lepší je používat Unicode.
Radek Chalupa
- vývoj software na zakázku
- školení programování (C/C++, WinAPI, ATL, COM, ActiveX, C#, NET Framework, MFC)
http://www.radekchalupa.cz
#12 end
Nevím co si představuješ pod "úspornějším kódem". Když už tak spíš by měla znít otázka na úspornější aplikaci (tj. paměťové nároky, velikost binárky).
Každé standardní okno musí být třídy kterou musíš zaregistrovat. Nebo použít dialogové okno a funkci DialogBox (a nemusíš registrovat třídu), ale musíš v resource skriptu nastavit minimalizační systémové tlačítko atd.
Samozřejmě je také možné v CreateWindow zadat jako třídu "Edit" (také už registrovanou pro standardní ovládací prvek), ale pak bys ho musel subclassovat aby jsi mohl jeho proceduru okna nastavit na vlastní funkci a obsloužit minimálně WM_DESTROY, jinak by totiž po zavření tohoto okna (jako hl. okna aplikace) zůstal exe stále běžet (resp. čekat ve frontě na zprávy, která by nechodily).
Radek Chalupa
- vývoj software na zakázku
- školení programování (C/C++, WinAPI, ATL, COM, ActiveX, C#, NET Framework, MFC)
http://www.radekchalupa.cz
#15 end
Pokud to máš natvrdo v ANSI, tak ty texty prostě nech jen v uvozovkách. Akorát když se později rozhodně pro Unicode, budeš to muset u všech textů doplňovat...
Jaké vlastně používáš vývojové prostředí, když tam tyhle makra nejsou a v projektu je nastavený překlad pro ANSI?
Radek Chalupa
- vývoj software na zakázku
- školení programování (C/C++, WinAPI, ATL, COM, ActiveX, C#, NET Framework, MFC)
http://www.radekchalupa.cz
Tak dnes pokrok! :-) Vynechal jsem_T (nebo TEXT) a překladač si to vzal, vyzkoušel jsem to na notepad okně a změnilo se obojí, jak hlavička, tak se i zapsal text do okna. Tak jsem si přepsal ony textové proměnné (identifikace okna), aby se mi text objevil v tom mém okně mojí aplikace, co jsem vkládal kod sem do vlákna. Zde se mi změnila jen hlavička okna, do vlastního okna se mi text nevypsal. Úsudkem - uvažuji, že zřejmě nelze zapisovat (nebo zobrazovat text), asi musím mít ještě něco povoleno, nebo nastaveno nebo ?? něco ještě jinak.
Poradil byste, prosím? Děkuji.
Já používám Dev-C++ (bylo mi doporučeno, že toho tam pro začátečníka není tolik. I tak je toho tady nějak až mi z toho jde hlava kolem)
#17 end
Notepad má v hl. okně vložené další okno (edit control) právě pro zápis textu, takže v aplikaci s jedním oknem se text nastaví pouze do titulku.
Vzhledem k tomu jak se ptáš tak doporučuji se nejdříve naučit alespoň základy WinAPI a pak se pouštět do podobných věcí jako "komunikace" mezi 2 procesy. Začít můžeš např. zde: http://www.radekchalupa.cz/clanky/?kod=214&obsah=1
Jako vývojové prostředí bych rozhodně doporučil MS Visual C++, resp. Visual Studio. V express verzi je zcela zdarma.
Radek Chalupa
- vývoj software na zakázku
- školení programování (C/C++, WinAPI, ATL, COM, ActiveX, C#, NET Framework, MFC)
http://www.radekchalupa.cz
#21 end
To jsou samozřejmě různě staré verze, nejlepší bude použít tu nejnovější, tj. 2013.
Radek Chalupa
- vývoj software na zakázku
- školení programování (C/C++, WinAPI, ATL, COM, ActiveX, C#, NET Framework, MFC)
http://www.radekchalupa.cz
Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku