Tässä teille extreme päänvaivaa.
Kyseessä on omatekemä Visual Basic 6 UserControl. Kyseinen kontrolli käyttää bittikarttamaskia, ja tilanteesta riippuen kontrollin pinnalle renderöidään STD-kuva, joka näyttää sitten käytössä lähinnä vaan ns. custom-shaped kontrollille.
Ongelma on se, että kun hiiren läsnäolo kontrollin päällä tunnistetaan vaikka MouseOverilla, pitää kuitenkin myös tunnistaa, milloin hiiri lakkaa leijumasta siinä. En ole keksinyt toistaiseksi vielä mitään tapaa, koska kontrollin muoto ja "isännättömyys". (ei voida käyttää apuna MouseOveria kontrollin ulkopuolelta, koska ulkopuolella ei ole mitään) Nämä karsii pois kaikki perusvaihtoehdot.
Ketään minua viisaampaa ?
Kaappaat (capture) hiiren ja kun se menee panelin ulkopuolelle vapautat ja ajat tarvittavat koodit.
Mitenkähän tämä kyseinen tapahtuma toteutetaan? Onko jossain koodinpätkää jossa vastaavanlaista on toteutettu ? Ei nimittäin harmainta aavistusta, miten selvitän tämän panelin ulkopuolelle luiskahtamisen.
Noin 5,2 miljoonaa tulosta: http://www.google.fi/search?q=capture mouse vb6
Käytännösä siis WinAPIa käyttäen mutta valmiita kirjastojakin löytyy
Ymmärtänet toivottavasti, että tuosta ei ole mitään apua ellet pysty sen merkittävämpää yhteyttä luomaan ehdotuksesi (hiiren liikkeiden seurannan) ja selittämäni ongelman välille. Toisin sanoen, et onnistunut auttamaan millään tavalla.
Miinaharavapelissä, toteuttaessani hiirikursorin alla olevan peliruudun korostusta päädyin ensin kokeilemaan hiirikursorin focus monitorin käyttöä. Tämä toimi kohtuullisesti, varsinkin jos kontrollin ympärille jätti pienen "kehyksen". Silti oli mahdollista nopealla hiiren heilautuksella saada kursori lennähtämään suoraan ohjelmaikkunan ulkopuolelle ilman, että tapahtuma rekisteröityisi.
Oma ratkaisuni ei varmaan ole mitenkään elegantti, mutta päädyin käyttämään ajastinta pollaamaan hiirikursorin sijaintia:
Fortranilla:
integer function timer_func() integer :: i type(POINT) :: pt call GetCursorPos(pt) call ScreenToClient(gr_handle, pt) if (pt%x.lt.0.or.pt%x.gt.gr_size.or.pt%y.lt.0.or.pt%y.gt.gr_size) then i = copy_graphics_region@(g_handle,0,0,gr_size,gr_size,r_handle,0,0,gr_size,gr_size,SRCCOPY) end if timer_func=1 end function timer_func
Freeze kirjoitti:
Toisin sanoen, et onnistunut auttamaan millään tavalla.
Ymmärtänet, että ohjelmoidessa joutuu myös itse tekemään jotain. On toki valitettavaa, että antamani eväät ongelman ratkaisuun eivät sinua innostaneet.
Mutta jos nyt tosiaan ongelma on, että et lainkaan ymmärtänyt mitä tarkoitin, niin laitetaan nyt vielä pseudokoodi suorakaiteen muotoisen kontrollin tarpeisiin:
Kontrolliin muuttuja: isMouseCaptured onmouseover-eventtiin: if isMouseCaptured then if x<0 or y<0 or x>usercontrol.width or y>usercontrol.height then ReleaseMouse isMouseCaptured = false '"hiiri poistui kontrollin alueelta" -reagoimisen koodi tähän end if else CaptureMouse isMouseCaptured = true 'hiiri saapui kontrollin alueelle end if usercontrollin destroy-eventtiin: if isMouseCaptured then ReleaseMouse
Hiiren kaappaamiseen liittyvät capturemouse ja releasmouse toteutus parhaaksi katsomallasi tavalla, eli joko suoraan WinAPIa käyttäen tai jotain valmista kirjastoa hyödyntäen.
Grez kirjoitti:
Mutta jos nyt tosiaan ongelma on, että et lainkaan ymmärtänyt mitä tarkoitin, niin laitetaan nyt vielä pseudokoodi suorakaiteen muotoisen kontrollin tarpeisiin
Juurikin tästä oli kyse. Kyseinen kontrolli kuitenkin saattaa olla minkä tahansa muotoinen (muoto määräytyy bittikarttamaskin perusteella), jolloin sitä ei voi ennalta päätellä.
Vaihtoehdot mitä olen tähän mennessä miettinyt: ajastin, joka käynnistyy jokaisen mouseover eventin lopussa, ja menee pois päältä sen alussa. kun jatkuva mouseover-floodi loppuu (mouseover syöte kontrollin päällä on jatkuvaa, vaikka hiiri ei liiku), mikäli uutta triggeriä mouseoveriin ei saada esim. 100ms kuluessa, ja ajastin kuluu lopppuun, oletetaan että hiiri on poistunut kontrollilta
Toinen vaihtoehto, tunnistetaan kontrollin hWnd hDC ym, ja APIlla kurkitaan osuuko hiiri kyseiseen kontrolliin.
Freeze kirjoitti:
Juurikin tästä oli kyse. Kyseinen kontrolli kuitenkin saattaa olla minkä tahansa muotoinen (muoto määräytyy bittikarttamaskin perusteella), jolloin sitä ei voi ennalta päätellä.
No eihän tuossa tarvitse mitään muuta kuin muuttaa osumistarkistusta niin, että jos se on bittikartan suorakaiteen sisällä, niin ei oleteta suoraan osuvaksi vaan tarkistetaan osuuko vai ei.
Grez kirjoitti:
No eihän tuossa tarvitse mitään muuta kuin muuttaa osumistarkistusta niin, että jos se on bittikartan suorakaiteen sisällä, niin ei oleteta suoraan osuvaksi vaan tarkistetaan osuuko vai ei.
Ei ehkä kannata vastata ollenkaan mikäli ei keskittyminen riitä ongelman lukemiseen tai ymmärtämiseen ajatuksella, kun tosiaan näitä puolikuntoisia vastauksia näyttää tulevan.
Kontrolli on edelleenkin bittikarttamaskin muotoinen = ei minkäänlaista osumistarkistusta tämän (maskatun) alueen ulkopuolella = ei kontrollia tämän alueen ulkopuolella. Joten, mouseover naksahtaa päälle vain ja ainoastaan, mikäli se hiiri tosiaan pyörii siellä bittikarttamaskin sallitulla alueella. Perusasioita.
Freeze kirjoitti:
ajastin, joka käynnistyy jokaisen mouseover eventin lopussa, ja menee pois päältä sen alussa. kun jatkuva mouseover-floodi loppuu (mouseover syöte kontrollin päällä on jatkuvaa, vaikka hiiri ei liiku), mikäli uutta triggeriä mouseoveriin ei saada esim. 100ms kuluessa, ja ajastin kuluu lopppuun, oletetaan että hiiri on poistunut kontrollilta
Tuo ajatus toimii itseasiassa aika hyvin, ajastin kuluu loppuun, ja käynnistyy uudelleen sen mukaan miten hiirtä heilutellaan, mutta mikäli hiiri on yhä kontrollin päällä, ei muutoksia painikkeen ulkoasuun tehdä.
Freeze kirjoitti:
Grez kirjoitti:
No eihän tuossa tarvitse mitään muuta kuin muuttaa osumistarkistusta niin, että jos se on bittikartan suorakaiteen sisällä, niin ei oleteta suoraan osuvaksi vaan tarkistetaan osuuko vai ei.
Ei ehkä kannata vastata ollenkaan mikäli ei keskittyminen riitä ongelman lukemiseen tai ymmärtämiseen ajatuksella, kun tosiaan näitä puolikuntoisia vastauksia näyttää tulevan.
Kuningasten kiitollisuus ja niin edelleen. Mikä risoo?
Freeze kirjoitti:
Kontrolli on edelleenkin bittikarttamaskin muotoinen = ei minkäänlaista osumistarkistusta tämän (maskatun) alueen ulkopuolella = ei kontrollia tämän alueen ulkopuolella. Joten, mouseover naksahtaa päälle vain ja ainoastaan, mikäli se hiiri tosiaan pyörii siellä bittikarttamaskin sallitulla alueella. Perusasioita.
Freeze kirjoitti:
ajastin, joka käynnistyy jokaisen mouseover eventin lopussa, ja menee pois päältä sen alussa. kun jatkuva mouseover-floodi loppuu (mouseover syöte kontrollin päällä on jatkuvaa, vaikka hiiri ei liiku), mikäli uutta triggeriä mouseoveriin ei saada esim. 100ms kuluessa, ja ajastin kuluu lopppuun, oletetaan että hiiri on poistunut kontrollilta
Tuo ajatus toimii itseasiassa aika hyvin, ajastin kuluu loppuun, ja käynnistyy uudelleen sen mukaan miten hiirtä heilutellaan, mutta mikäli hiiri on yhä kontrollin päällä, ei muutoksia painikkeen ulkoasuun tehdä.
No jos kerran saat aina kiinni hiiren meni se mihin tahansa (random-shaped-bittikarttoja jotka jostain syystä eivät suorakaiteeseen tallennettuja bittikarttoja vaan jotain ihan muuta. ehkä linkattu lista koordinaateista tai jokin muu täysin uraa uurtava bittikarttaesitys?), niin mitä jos laittaisit sille taustallekin mouseoverin. Sitten sinulla yleisesti accessoitava paikka, jossa ylläpidät aktiivista (mikä on hoverattu) elementtiä. Kun elementti vaihtuu, kutsut vanhan elementin mouseOuttia.
Peukut ylös tälle minua edeltäneelle kommentoijalle, sen verran oli jo poika kujalla!
Mikäli täällä olisi oikeasti ketään avuliasta liikkunut siihen aikaan kun tuon alkuperäisen viestin postasin, olisi hän mitä ilmeisimmin löytänyt tämän :)
Freeze kirjoitti:
Mikäli täällä olisi oikeasti ketään avuliasta liikkunut siihen aikaan kun tuon alkuperäisen viestin postasin, olisi hän mitä ilmeisimmin löytänyt tämän :)
Jaa, meidän ois pitäny googlettaa sun puolesta? No, hyvä, että löysit.
Jaksat nähdä ihan tosissaan vaivaa tuon trollaamisen kanssa, vai kuinka?
Lisäys:
Freeze kirjoitti:
Peukut ylös tälle minua edeltäneelle kommentoijalle, sen verran oli jo poika kujalla!
Jaksat nähdä ihan tosissaan vaivaa tuon trollaamisen kanssa, vai kuinka?
Heh, tälle jo vähän naurahdin.
Ensimmäinen postaus: Freeze [07.08.2012 23:36:44]
Freezer löytänyt ratkaisun: Freeze [09.08.2012 13:23:30]
eli olit paininut tämän ongelman kanssa n. 2htp:tä. Melkein jo naureskelen ajatukselle että miten meinaat tämän hukkaan heitetyn ajan asiakkaalta laskuttaa :D
Noin pienelle ongelmalle 2htp:tä on meinaan aika paljon, kyse on kuitenkin vain mouseoverin bindauksesta kontrolliin.
Mikäli taas teet talon sisäistä projektia, suosittelisin kyllä alan vaihtoa ellei vähän tehokkaammaksi ala tuo työskentelysi.
(Tuolla linkkaamassasi osoitteessa oli parasta seuraava lause:
lainaus:
Another way is to start using VB.NET which has these events built-in.
Koska jos vb6 tuottaa noin paljon ongelmia sinulle, suosittelisin modernimpaan (VB.NET, jos visual basic nyt sattuu olemaan se sinun juttusi) siirtymistä. Ei oikein ole järkeä lähteä opettelemaan vanhaa, ellei ole jotain pätevää syytä moiseen.
Blaze kirjoitti:
Jaa, meidän ois pitäny googlettaa sun puolesta? No, hyvä, että löysit.
Teettekö te sitten yleensä jotain muuta täällä putkan foorumilla muiden ongelmien ratkaisemiseksi ? Ette.
syyskimo kirjoitti:
Jaksat nähdä ihan tosissaan vaivaa tuon trollaamisen kanssa, vai kuinka?
Jaksat nähdä ihan tosissaan vaivaa näissä replyissä, kirjotat saman asian oikein kahteen kertaan, vai kuinka?
groovyb kirjoitti:
eli olit paininut tämän ongelman kanssa n. 2htp:tä. Melkein jo naureskelen ajatukselle että miten meinaat tämän hukkaan heitetyn ajan asiakkaalta laskuttaa :D
Ei tainnut käväistä mielessä, että asioita voi tehdä muutenkin kuin työkseen?
Tämäkin asia on kieltämättä suorastaan hulvaton, löydät sen hauskuuden varmasti, heh ?
Kun suorastaan tikahtuneena lakkaat nauramasta sille, muistutan vielä siitä, ettei monikaan työskentelisi VB6 parissa nykypäivänä.
Näin hätäisesti arvioituna aika, mikä yhteensä tuli käytettyä tuon ongelman parissa, taisi jäädä alle kahteen tuntiin.
groovyb kirjoitti:
Koska jos vb6 tuottaa noin paljon ongelmia sinulle, suosittelisin modernimpaan (VB.NET, jos visual basic nyt sattuu olemaan se sinun juttusi) siirtymistä. Ei oikein ole järkeä lähteä opettelemaan vanhaa, ellei ole jotain pätevää syytä moiseen.
Mikähän on tuulesta temmattujen päätelmien maailmanennätys? Tämä saattoi olla Ohjelmointiputkan. Mutta teenpäs minäkin johtopäätöksen, et sovi asiakaspalveluun, joten mikäli olet tällä alalla, siirry takaisin koodaukseen, se voi olla ainoa asia, mitä mahdollisesti osaat.
Jos haluaa hyvää palvelua, pitää olla myös kohtelias asiakas. True?
groovyb kirjoitti:
Jos haluaa hyvää palvelua, pitää olla myös kohtelias asiakas. True?
Negative. Hyvää palvelua voi antaa myös ärsyttäville asiakkaille (ns. aasiakkaille).
groovyb kirjoitti:
Jos haluaa hyvää palvelua, pitää olla myös kohtelias asiakas. True?
Eh, ei tosiaan. Asiakas on aina oikeassa ;)
Voi, mutta silloin kyse on palkkatyöstä, eikä vapaa-ajan tuhlaamisesta ärsyttäviin henkilöihin.
Puhutko nyt asiakkaasta vai henkilöstä, joka pyytää palvelusta?
Henkilöistä nyt on kyse, vaikka niitähän ne asiakkatkin on. Jos asiakas käyttäytyisi huonosti pyytäessään vaikka mahdollisuutta siihen että tekisin vapaa-ajallani töitä, jäisi kyllä tekemättä. Mutta jos nyt kyse on foorumitörttöilystä jota anonyyminä on niin helppo harrastaa, on turha kauhalla pyytää jos lusikalla on annettu.
Suosittelen toki avautumista henkilökohtaisista ongelmista lämpimästi jossain muualla kuin offtopiccina keskusteluissa / jatkona jo päätettyihin threadeihin, esim hyvä sauma tälle voisi olla psykiatrin kanssa :)
Freeze kirjoitti:
Ei ehkä kannata vastata ollenkaan mikäli ei keskittyminen riitä ongelman lukemiseen tai ymmärtämiseen ajatuksella
Oikeastaanhan kyse on siitä, ettei sinun ehkä kannattaisi ohjelmoida ollenkaan, kun ei ymmärrys riitä yksinkertaisen ohjelman ratkaisuun, vaikka siihen ratkaisuun tarvittavat vihjeet annetaan. Eli edes alkeellisella ohjelmointi- ja ongelmanratkaisutaidolla ja VB6:lla kuvaamasi ongelman ratkaisu antamillani vinkeillä olisi ollut ehkä tunnin homma.
Eli oikeassa olet, ei ehkä kannata vastata (sinulle) ollenkaan, kun asenne ja vinkkien vastaanottohalu on tuota luokkaa.
Grez kirjoitti:
Oikeastaanhan kyse on siitä, ettei sinun ehkä kannattaisi ohjelmoida ollenkaan, kun ei ymmärrys riitä yksinkertaisen ohjelman ratkaisuun, vaikka siihen ratkaisuun tarvittavat vihjeet annetaan. Eli edes alkeellisella ohjelmointi- ja ongelmanratkaisutaidolla ja VB6:lla kuvaamasi ongelman ratkaisu antamillani vinkeillä olisi ollut ehkä tunnin homma.
Ja sinun ymmärrys ei nähtävästi riitä edes yksinkertaisen, ymmärrettävän suomen kielen lauseen tuottamiseen - ei taida olla äidinkielesi ?
Kuitenkin lopulta, sain ratkaisevan vinkin omalta lemmikkisimpanssiltani. Auttoi vielä koodauksessakin sen verran varpaillaan että meni loppujenlopuksi koko urakassa alle muutaman minuutin. Eli sinuun verrattuna simpanssi pärjäsi aika hyvin, tosin, sen koodaustaidot on kehittyneet alkeellisesta jo vähän pidemmälle ;)
Kaikesta huolimatta oikein mukavaa alkavaa syksyä teille kaikille, vaikka mitäpä te siitä, kesät talvet - kaikki näyttää samalta yksin pimeässä huoneessa tietokoneen äärellä, eikös? :)
Freeze kirjoitti:
Ja sinun ymmärrys ei nähtävästi riitä edes yksinkertaisen, ymmärrettävän suomen kielen lauseen tuottamiseen - ei taida olla äidinkielesi ?
On se äidinkieleni. Tosiaan, en tainnut ymmärtää kirjoittaa riittävän yksinkertaisesti.
Hienoa että simpanssisi hoitaa minuutissa sen mitä itse pähkäilit monena päivänä. Alunperin laitoin viestiin lyhyemmän ajan, mutta muutin sen tunniksi ettei sinulle tulisi paha mieli.
Grez kirjoitti:
Alunperin laitoin viestiin lyhyemmän ajan, mutta muutin sen tunniksi ettei sinulle tulisi paha mieli.
Kiitos, olet huomaavainen. Nyt ei tarvitse enää miettiä, mistä hyvä mieleni johtui. :)
Ehkä kohta joku putkalainen saa idean toteuttaa foorumin toisella tavalla.
Mitä ihan itse aiheeseen tulee, niin VB6:n UserControlit osaa olla aikamoisia kökkömöhkäleitä. Moni kiva toiminnallisuus (kuten tämä) vaatii subclassaamisen, joka taas puolestaan tekee UserControlista varsin kaatumisherkän kehittämisvaiheessa. Eritoten UserControlin liittäminen projektiin kääntämättömänä saattaa nopeasti aiheuttaa yllättäviä kaatumisia, mutta toisaalta myös käännetyt UserControlit saattavat lomaketta muokatessa yllättäen kaatua ja hukata kaikki asetuksensa. Ja tämä saattaa tapahtua ihan yksinkertaisista yksinkertaisimmallakin UserControlilla, jossa mikään oma pätkä koodia ei voi itsessään aiheuttaa kaatumista.
Subclassaamista varten löytyy kaatumisherkkyyttä hiukan helpottava SelfSub-koodinpätkä netistä, joka tekee subclassaamisesta hieman turvallisempaa kehittämisvaiheessa (ettei ainakaan Stop-nappulan painaminen kaada IDE:ä), mutta sekään ei aina aivan täydellinen ole.
Onneksi edes lopullisissa käännetyissä ohjelmissa ongelmia on vähemmän.
Merri kirjoitti:
...
...Kaatuu jos luokkaa ei terminoida oikein - ymmärrettävää, onhan siihen syitä.
Aihe on jo aika vanha, joten et voi enää vastata siihen.