zypher_ut Skrevet 8. februar 2005 Del Skrevet 8. februar 2005 Kan noen forklare meg - helst så enkelt som mulig - hva subclassing er? Lenke til kommentar
kaffenils Skrevet 8. februar 2005 Del Skrevet 8. februar 2005 Et søk i google gir f.eks denne siden Jeg har bare brukt subclassing en gang, og det var for å håndtere mousewheel-hendelser i et form. Lenke til kommentar
aadnk Skrevet 8. februar 2005 Del Skrevet 8. februar 2005 (endret) Alle vinduer (f.eks. en form, en knapp, en listeboks osv.) i Windows har spesifisert en funksjon som operativsystemet eller andre programmer kan kalle for å kommunisere med programmet. Windows kan f.eks. sende hendelser som når musepekeren kommer over vinduet, en tast sendes til vinduet og mye mer. Programmer kan på sin side sende forespørsel om spesielle opplysninger angående vinduet; eksempelvis vil EM_GETLINECOUNT få en tekstboks til å sende tilbake antall linjer i teksten. Man kan også definere sine egne "funksjoner". For å kalle disse spesielle funksjonene, kan man bruke enten PostMessage, SendMessage eller CallWindowProc (forutsetter at man kjenner adressen til prosedyren). Vanligvis ser en slik funksjon ut som sådan: Public Function WindowProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long ' Din kode her Select Case uMsg Case 0 ' Noe her Case 1 ' Noe her End Select WindowProc = 0 ' Returner en verdi til avsender End Function I denne funksjonen er hwnd adressen eller pekeren til vinduet avsenderen har prøvd å nå; uMsg er ID-en til funksjonen/hendelsen eller hva enn anropet gjalt; wParam er en valgfri variabel som benyttes til flere forskjellige hensikter, avhengig av ID-en - likeså er det med lParam. Dersom jeg for eksempel ønsker å sette tittelbaren på en form, kunne jeg uten problemer gjort som følger: Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Integer, ByVal lParam As Any) As Long Private Const WM_SETTEXT = &HC Private Sub Form_Load() SendMessage Me.hwnd, WM_SETTEXT, 0&, "Dette er en test" End Sub Mottakeren ville så fått en melding til sin vindu-funksjon, omtrent som dette: Public Function WindowProc( ... ) As Long ' hwnd er nå lik Me.hwnd, uMsg er WM_SETTEXT, wParam er 0 og lParam er ' "Dette er en test" ' Det ser neppe slik ut i virkeligheten, men det gir et godt bilde Select Case uMsg Case WM_SETTEXT Me.Caption = lParam 'Case ... (mange flere her) End Select End Function Hva er så poenget med subclassing? Jo, i denne teknikken overstyrer vi rett og slett et programs egentlige vindu-funksjon ved å legge inn vår egen, og dernest sende eller la være å sende meldingen videre - alt etter hva vi ønsker. For å spesifisere vår egen vindu-funksjon, bruker vi API-kallet SetWindowLong. Studer og legg følgende eksempel inn i en modul: Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Declare Function SetClipboardViewer Lib "user32" (ByVal hwnd As Long) As Long Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Integer, ByVal lParam As Any) As Long Public Const WM_SETTEXT = &HC Public Const GWL_WNDPROC = (-4) Private PrevProc As Long ' Den originale funksjonen Public Sub SubclassForm(F As Form) ' AddressOf WindowProc = gir adressen til funksjonen PrevProc = SetWindowLong(F.hwnd, GWL_WNDPROC, AddressOf WindowProc) End Sub Public Sub SubclassForm(F As Form) ' Det er SVÆRT viktig at vi tilbakestiller subclassingen. Dersom dette ikke blir gjort, krasjer hele VB SetWindowLong F.hwnd, GWL_WNDPROC, PrevProc End Sub Public Function WindowProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Dim sTemp As String If uMsg = WM_SETTEXT Then ' Ikke la den egentlige teksten komme frem, erstatt den med vår egen sTemp = StrConv("Overstyring" & Chr(0), vbFromUnicode) lParam = StrPtr(sTemp) End If ' Kall den originiale funksjonen WindowProc = CallWindowProc(PrevProc, hwnd, uMsg, wParam, lParam) End Function Legg så inn en form med knappen cmdTest, og legg til følgende kode i formen: Private Sub cmdTest_Click() SendMessage Me.hwnd, WM_SETTEXT, 0&, "Dette er en test" End Sub Private Sub Form_Load() ' Starter subclassingen SubclassForm Me End Sub Private Sub Form_Unload(Cancel As Integer) ' Dersom du stopper prosjekter (med eksempelvis stoppknappen) uten at denne blir kalt, kan det gå ille SubclassForm Me End Sub Når du så trykker på knappen cmdTest, vil du se at teksten som kommer opp i tittelvinduet er ikke "Dette er en test", men "Overstyring". Dette har forhåpentligvis illustert bruken og teknikken bak subclassing på en forståelig og grei måte, men du kan, dersom det fremdeles er litt uklart, lese litt på denne utmerkede siden her. Skjønt, da må du nok belage deg på å lese engelsk, dessverre. Endret 8. februar 2005 av aadnk Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå